From 5015749f707dcdb1d91788bc459a53af88003949 Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 3 Jun 2024 19:31:25 +0200 Subject: [PATCH 001/124] chore: streamline the naming to indicate more than graph support Signed-off-by: SoXX --- README.md | 22 +++++------ go.mod | 7 +++- go.sum | 6 +++ internal/logger.go | 8 ++-- internal/post.go | 4 +- internal/relationships.go | 6 +-- internal/source.go | 8 ++-- internal/tag.go | 4 +- internal/user.go | 16 ++++---- pkg/{graph/graph.go => database/database.go} | 38 +++++++++---------- pkg/{graph/impl.go => database/graph_impl.go} | 2 +- 11 files changed, 66 insertions(+), 55 deletions(-) rename pkg/{graph/graph.go => database/database.go} (86%) rename pkg/{graph/impl.go => database/graph_impl.go} (99%) diff --git a/README.md b/README.md index 126a1b6..732fd42 100644 --- a/README.md +++ b/README.md @@ -17,20 +17,20 @@ Here's a simple usage example: package main import ( - "context" - "fmt" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/graph" + "context" + "fmt" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/database" ) func main() { - client := graph.NewGraphConnection() - err := client.Connect(context.Background(), "your-endpoint", "your-username", "your-password") - if err != nil { - fmt.Println(err) - return - } - // further usage of the client... + client := graph.NewGraphConnection() + err := client.Connect(context.Background(), "your-endpoint", "your-username", "your-password") + if err != nil { + fmt.Println(err) + return + } + // further usage of the client... } ``` diff --git a/go.mod b/go.mod index 8593a08..37b8e64 100644 --- a/go.mod +++ b/go.mod @@ -7,4 +7,9 @@ require ( github.com/sirupsen/logrus v1.9.3 ) -require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect +require ( + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect + gorm.io/gorm v1.25.10 // indirect +) diff --git a/go.sum b/go.sum index b7d2bdf..a7307ff 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,10 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/neo4j/neo4j-go-driver/v5 v5.17.0 h1:Bdqg1Y8Hd3uLYToXtBjysDYXTdMiP7zeUNUEwfbJkSo= github.com/neo4j/neo4j-go-driver/v5 v5.17.0/go.mod h1:Vff8OwT7QpLm7L2yYr85XNWe9Rbqlbeb9asNXJTHO4k= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -15,3 +19,5 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= +gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= diff --git a/internal/logger.go b/internal/logger.go index 446869d..5522934 100644 --- a/internal/logger.go +++ b/internal/logger.go @@ -19,21 +19,21 @@ func (n graphLogger) Error(name string, id string, err error) { log.WithFields(log.Fields{ "name": name, "id": id, - }).Errorf("graph: %s", err) + }).Errorf("database: %s", err) } func (n graphLogger) Warnf(name string, id string, msg string, args ...any) { log.WithFields(log.Fields{ "name": name, "id": id, - }).Warnf("graph: %v", fmt.Sprintf(msg, args...)) + }).Warnf("database: %v", fmt.Sprintf(msg, args...)) } func (n graphLogger) Infof(name string, id string, msg string, args ...any) { log.WithFields(log.Fields{ "name": name, "id": id, - }).Infof("graph: %v", fmt.Sprintf(msg, args...)) + }).Infof("database: %v", fmt.Sprintf(msg, args...)) } func (n graphLogger) Debugf(name string, id string, msg string, args ...any) { @@ -41,6 +41,6 @@ func (n graphLogger) Debugf(name string, id string, msg string, args ...any) { log.WithFields(log.Fields{ "name": name, "id": id, - }).Debugf("graph: %v", fmt.Sprintf(msg, args...)) + }).Debugf("database: %v", fmt.Sprintf(msg, args...)) } } diff --git a/internal/post.go b/internal/post.go index 021a841..78136ac 100644 --- a/internal/post.go +++ b/internal/post.go @@ -26,7 +26,7 @@ func CreateAnthrovePostNode(ctx context.Context, driver neo4j.DriverWithContext, log.WithFields(log.Fields{ "anthrove_post_id": anthrovePost.PostID, "anthrove_post_rating": anthrovePost.Rating, - }).Trace("graph: created anthrove post") + }).Trace("database: created anthrove post") return nil } @@ -106,7 +106,7 @@ func executeCheckQuery(ctx context.Context, driver neo4j.DriverWithContext, quer log.WithFields(log.Fields{ "anthrove_post_id": anthrovePost.PostID, "anthrove_post_exists": exists, - }).Trace("graph: checked if post exists") + }).Trace("database: checked if post exists") if !exists { return nil, exists, nil diff --git a/internal/relationships.go b/internal/relationships.go index 7e18bca..6d12ddc 100644 --- a/internal/relationships.go +++ b/internal/relationships.go @@ -33,7 +33,7 @@ func EstablishAnthrovePostToSourceLink(ctx context.Context, driver neo4j.DriverW "anthrove_post_id": anthrovePostID, "source_post_url": anthrovePostRelationship.Url, "source_post_id": anthrovePostRelationship.PostID, - }).Trace("graph: creating anthrove post to source link") + }).Trace("database: creating anthrove post to source link") return nil } @@ -59,7 +59,7 @@ func EstablishUserToPostLink(ctx context.Context, driver neo4j.DriverWithContext log.WithFields(log.Fields{ "anthrove_post_id": anthrovePost.PostID, "anthrove_user_id": anthroveUser.UserID, - }).Trace("graph: created user to post link") + }).Trace("database: created user to post link") return nil } @@ -94,7 +94,7 @@ func CheckUserToPostLink(ctx context.Context, driver neo4j.DriverWithContext, an "relationship_exists": exists, "relationship_anthrove_user_id": anthroveUserID, "relationship_e621_post_id": "", - }).Trace("graph: checked user post relationship") + }).Trace("database: checked user post relationship") return exists, nil } diff --git a/internal/source.go b/internal/source.go index bb91fdf..e3c36a6 100644 --- a/internal/source.go +++ b/internal/source.go @@ -22,14 +22,14 @@ func CreateSourceNode(ctx context.Context, driver neo4j.DriverWithContext, anthr _, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) if err != nil { - return fmt.Errorf("graph: %w", err) + return fmt.Errorf("database: %w", err) } log.WithFields(log.Fields{ "node_source_url": anthroveSource.Domain, "node_source_displayName": anthroveSource.DisplayName, "node_source_icon": anthroveSource.Icon, - }).Trace("graph: created source node") + }).Trace("database: created source node") return nil } @@ -70,7 +70,7 @@ func GetAllSourceNodes(ctx context.Context, driver neo4j.DriverWithContext) ([]m log.WithFields(log.Fields{ "tag_amount": len(sources), - }).Trace("graph: created tag node") + }).Trace("database: created tag node") return sources, nil } @@ -107,7 +107,7 @@ func GetSourceNodesByURL(ctx context.Context, driver neo4j.DriverWithContext, so log.WithFields(log.Fields{ "source_url": sourceUrl, - }).Trace("graph: got source node") + }).Trace("database: got source node") return &source, nil } diff --git a/internal/tag.go b/internal/tag.go index 3e5a02d..b91d1cb 100644 --- a/internal/tag.go +++ b/internal/tag.go @@ -29,7 +29,7 @@ func CreateTagNodeWitRelation(ctx context.Context, driver neo4j.DriverWithContex "anthrove_post_id": anthrovePostID, "tag_name": anthroveTag.Name, "tag_type": anthroveTag.Type, - }).Trace("graph: created tag node") + }).Trace("database: created tag node") return nil } @@ -78,7 +78,7 @@ func GetTags(ctx context.Context, driver neo4j.DriverWithContext) ([]models.Tags log.WithFields(log.Fields{ "tag_amount": len(userTags), - }).Trace("graph: created tag node") + }).Trace("database: created tag node") return userTags, nil } diff --git a/internal/user.go b/internal/user.go index a1128ec..5e9fe4d 100644 --- a/internal/user.go +++ b/internal/user.go @@ -46,7 +46,7 @@ func CreateUserNodeWithSourceRelation(ctx context.Context, driver neo4j.DriverWi "source_user_id": userID, "source_user_name": username, "source_domain": sourceDomain, - }).Trace("graph: crated user with relationship") + }).Trace("database: crated user with relationship") return nil } @@ -85,7 +85,7 @@ func GetUserFavoritesCount(ctx context.Context, driver neo4j.DriverWithContext, log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, "anthrove_user_fav_count": userFavoriteCount, - }).Trace("graph: got user favorite count") + }).Trace("database: got user favorite count") return userFavoriteCount, nil } @@ -145,7 +145,7 @@ func GetUserSourceLink(ctx context.Context, driver neo4j.DriverWithContext, anth log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, "anthrove_data": userSource, - }).Trace("graph: got user favorite count") + }).Trace("database: got user favorite count") return userSource, nil } @@ -206,7 +206,7 @@ func GetSpecifiedUserSourceLink(ctx context.Context, driver neo4j.DriverWithCont log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, "anthrove_data": userSource, - }).Trace("graph: got user favorite count") + }).Trace("database: got user favorite count") return userSource, nil } @@ -273,7 +273,7 @@ func GetAnthroveUser(ctx context.Context, driver neo4j.DriverWithContext, anthro log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, - }).Trace("graph: got anthrove user") + }).Trace("database: got anthrove user") return &anthroveUser, nil @@ -310,7 +310,7 @@ func GetAllAnthroveUserIDs(ctx context.Context, driver neo4j.DriverWithContext) log.WithFields(log.Fields{ "anthrove_user_id_count": len(anthroveUsers), - }).Trace("graph: got al anthrove user IDs") + }).Trace("database: got al anthrove user IDs") return anthroveUsers, nil @@ -396,7 +396,7 @@ func GetUserFavoriteNodeWithPagination(ctx context.Context, driver neo4j.DriverW log.WithFields(log.Fields{ "anthrove_user_fav_count": len(favoritePosts), - }).Trace("graph: got al anthrove user favorites") + }).Trace("database: got al anthrove user favorites") return &models.FavoriteList{Posts: favoritePosts}, nil @@ -448,7 +448,7 @@ func GetUserTagNodeWitRelationToFavedPosts(ctx context.Context, driver neo4j.Dri log.WithFields(log.Fields{ "tag_amount": len(userTags), - }).Trace("graph: created tag node") + }).Trace("database: created tag node") return userTags, nil } diff --git a/pkg/graph/graph.go b/pkg/database/database.go similarity index 86% rename from pkg/graph/graph.go rename to pkg/database/database.go index 3cd7630..867e72a 100644 --- a/pkg/graph/graph.go +++ b/pkg/database/database.go @@ -1,4 +1,4 @@ -// Package graph provides a client for using the OtterSpace API. +// Package database provides a client for using the OtterSpace API. // // This package provides a client to interact with the OtterSpace API. It includes // methods for all API endpoints, and convenience methods for common tasks. @@ -11,11 +11,11 @@ // "context" // "fmt" // "git.dragse.it/anthrove/otter-space-sdk/pkg/models" -// "git.dragse.it/anthrove/otter-space-sdk/pkg/graph" +// "git.dragse.it/anthrove/otter-space-sdk/pkg/database" // ) // // func main() { -// client := graph.NewGraphConnection() +// client := database.NewGraphConnection() // err := client.Connect(context.Background(), "your-endpoint", "your-username", "your-password") // if err != nil { // fmt.Println(err) @@ -23,7 +23,7 @@ // } // // further usage of the client... // } -package graph +package database import ( "context" @@ -39,63 +39,63 @@ type OtterSpace interface { // It returns an error if the connection cannot be established. Connect(ctx context.Context, endpoint string, username string, password string) error - // AddUserWithRelationToSource adds a new user to the OtterSpace graph and associates them with a source. + // AddUserWithRelationToSource adds a new user to the OtterSpace database and associates them with a source. // It returns the newly created user and an error if the operation fails. AddUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error - // AddSource adds a new source to the OtterSpace graph. + // AddSource adds a new source to the OtterSpace database. // It returns an error if the operation fails. AddSource(ctx context.Context, anthroveSource *models.AnthroveSource) error - // AddPost adds a new post to the OtterSpace graph. + // AddPost adds a new post to the OtterSpace database. // It returns an error if the operation fails. AddPost(ctx context.Context, anthrovePost *models.AnthrovePost) error - // AddTagWithRelationToPost adds a new tag to the OtterSpace graph and associates it with a post. + // AddTagWithRelationToPost adds a new tag to the OtterSpace database and associates it with a post. // It returns an error if the operation fails. AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.AnthroveTag) error - // LinkPostWithSource establishes a link between a post and a source in the OtterSpace graph. + // LinkPostWithSource establishes a link between a post and a source in the OtterSpace database. // It returns an error if the operation fails. LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *models.AnthrovePostRelationship) error - // LinkUserWithPost establishes a link between a user and a post in the OtterSpace graph. + // LinkUserWithPost establishes a link between a user and a post in the OtterSpace database. // It returns an error if the operation fails. LinkUserWithPost(ctx context.Context, anthroveUser *models.AnthroveUser, anthrovePost *models.AnthrovePost) error - // CheckUserPostLink checks if a link between a user and a post exists in the OtterSpace graph. + // CheckUserPostLink checks if a link between a user and a post exists in the OtterSpace database. // It returns true if the link exists, false otherwise, and an error if the operation fails. CheckUserPostLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) - // CheckPostNodeExistsByAnthroveID checks if a post node exists in the OtterSpace graph by its Anthrove ID. + // CheckPostNodeExistsByAnthroveID checks if a post node exists in the OtterSpace database by its Anthrove ID. // It returns the post if it exists, a boolean indicating whether the post was found, and an error if the operation fails. CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *models.AnthrovePost) (*models.AnthrovePost, bool, error) - // CheckPostNodeExistsBySourceURL checks if a post node exists in the OtterSpace graph by its source URL. + // CheckPostNodeExistsBySourceURL checks if a post node exists in the OtterSpace database by its source URL. // It returns the post if it exists, a boolean indicating whether the post was found, and an error if the operation fails. CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*models.AnthrovePost, bool, error) - // CheckPostNodeExistsBySourceID checks if a post node exists in the OtterSpace graph by its source ID. + // CheckPostNodeExistsBySourceID checks if a post node exists in the OtterSpace database by its source ID. // It returns the post if it exists, a boolean indicating whether the post was found, and an error if the operation fails. CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*models.AnthrovePost, bool, error) - // GetUserFavoriteCount retrieves the count of a user's favorite posts from the OtterSpace graph. + // GetUserFavoriteCount retrieves the count of a user's favorite posts from the OtterSpace database. // It returns the count and an error if the operation fails. GetUserFavoriteCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) - // GetUserSourceLinks retrieves the links between a user and sources in the OtterSpace graph. + // GetUserSourceLinks retrieves the links between a user and sources in the OtterSpace database. // It returns a map of source domains to user-source relationships, and an error if the operation fails. GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.AnthroveUserRelationship, error) - // GetSpecifiedUserSourceLink GetUserSourceLinks retrieves the links between a user and a specific source in the OtterSpace graph. + // GetSpecifiedUserSourceLink GetUserSourceLinks retrieves the links between a user and a specific source in the OtterSpace database. // It returns a map of source domains to user-source relationships, and an error if the operation fails. GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.AnthroveUserRelationship, error) - // GetAnthroveUser retrieves a user from the OtterSpace graph by their ID. + // GetAnthroveUser retrieves a user from the OtterSpace database by their ID. // It returns the user and an error if the operation fails. GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*models.AnthroveUser, error) - // GetAllAnthroveUserIDs retrieves all user IDs from the OtterSpace graph. + // GetAllAnthroveUserIDs retrieves all user IDs from the OtterSpace database. // It returns a slice of user IDs and an error if the operation fails. GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) diff --git a/pkg/graph/impl.go b/pkg/database/graph_impl.go similarity index 99% rename from pkg/graph/impl.go rename to pkg/database/graph_impl.go index 6b1b3bb..68bc025 100644 --- a/pkg/graph/impl.go +++ b/pkg/database/graph_impl.go @@ -1,4 +1,4 @@ -package graph +package database import ( "context" -- 2.45.1 From ccc6010466710ea9ad371f76c8c37492aa047d92 Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 3 Jun 2024 19:32:25 +0200 Subject: [PATCH 002/124] chore: streamline the naming to indicate more than graph support Signed-off-by: SoXX --- internal/{ => graph}/logger.go | 2 +- internal/{ => graph}/post.go | 2 +- internal/{ => graph}/relationships.go | 2 +- internal/{ => graph}/source.go | 2 +- internal/{ => graph}/tag.go | 2 +- internal/{ => graph}/user.go | 2 +- pkg/database/graph_impl.go | 44 +++++++++++++-------------- 7 files changed, 28 insertions(+), 28 deletions(-) rename internal/{ => graph}/logger.go (98%) rename internal/{ => graph}/post.go (99%) rename internal/{ => graph}/relationships.go (99%) rename internal/{ => graph}/source.go (99%) rename internal/{ => graph}/tag.go (99%) rename internal/{ => graph}/user.go (99%) diff --git a/internal/logger.go b/internal/graph/logger.go similarity index 98% rename from internal/logger.go rename to internal/graph/logger.go index 5522934..914db3a 100644 --- a/internal/logger.go +++ b/internal/graph/logger.go @@ -1,4 +1,4 @@ -package internal +package graph import ( "fmt" diff --git a/internal/post.go b/internal/graph/post.go similarity index 99% rename from internal/post.go rename to internal/graph/post.go index 78136ac..6a39f51 100644 --- a/internal/post.go +++ b/internal/graph/post.go @@ -1,4 +1,4 @@ -package internal +package graph import ( "context" diff --git a/internal/relationships.go b/internal/graph/relationships.go similarity index 99% rename from internal/relationships.go rename to internal/graph/relationships.go index 6d12ddc..b77c8e6 100644 --- a/internal/relationships.go +++ b/internal/graph/relationships.go @@ -1,4 +1,4 @@ -package internal +package graph import ( "context" diff --git a/internal/source.go b/internal/graph/source.go similarity index 99% rename from internal/source.go rename to internal/graph/source.go index e3c36a6..cbdc690 100644 --- a/internal/source.go +++ b/internal/graph/source.go @@ -1,4 +1,4 @@ -package internal +package graph import ( "context" diff --git a/internal/tag.go b/internal/graph/tag.go similarity index 99% rename from internal/tag.go rename to internal/graph/tag.go index b91d1cb..0838b13 100644 --- a/internal/tag.go +++ b/internal/graph/tag.go @@ -1,4 +1,4 @@ -package internal +package graph import ( "context" diff --git a/internal/user.go b/internal/graph/user.go similarity index 99% rename from internal/user.go rename to internal/graph/user.go index 5e9fe4d..7d4a8e8 100644 --- a/internal/user.go +++ b/internal/graph/user.go @@ -1,4 +1,4 @@ -package internal +package graph import ( "context" diff --git a/pkg/database/graph_impl.go b/pkg/database/graph_impl.go index 68bc025..fac6a85 100644 --- a/pkg/database/graph_impl.go +++ b/pkg/database/graph_impl.go @@ -2,8 +2,8 @@ package database import ( "context" + "git.dragse.it/anthrove/otter-space-sdk/internal/graph" - "git.dragse.it/anthrove/otter-space-sdk/internal" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "github.com/neo4j/neo4j-go-driver/v5/neo4j" "github.com/neo4j/neo4j-go-driver/v5/neo4j/config" @@ -37,87 +37,87 @@ func (g *graphConnection) Connect(ctx context.Context, endpoint string, username } func (g *graphConnection) AddUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error { - return internal.CreateUserNodeWithSourceRelation(ctx, g.driver, anthroveUserID, sourceDomain, userID, username) + return graph.CreateUserNodeWithSourceRelation(ctx, g.driver, anthroveUserID, sourceDomain, userID, username) } func (g *graphConnection) AddSource(ctx context.Context, anthroveSource *models.AnthroveSource) error { - return internal.CreateSourceNode(ctx, g.driver, anthroveSource) + return graph.CreateSourceNode(ctx, g.driver, anthroveSource) } func (g *graphConnection) AddPost(ctx context.Context, anthrovePost *models.AnthrovePost) error { - return internal.CreateAnthrovePostNode(ctx, g.driver, anthrovePost) + return graph.CreateAnthrovePostNode(ctx, g.driver, anthrovePost) } func (g *graphConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.AnthroveTag) error { - return internal.CreateTagNodeWitRelation(ctx, g.driver, anthrovePostID, anthroveTag) + return graph.CreateTagNodeWitRelation(ctx, g.driver, anthrovePostID, anthroveTag) } func (g *graphConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *models.AnthrovePostRelationship) error { - return internal.EstablishAnthrovePostToSourceLink(ctx, g.driver, anthrovePostID, anthroveSourceDomain, anthrovePostRelationship) + return graph.EstablishAnthrovePostToSourceLink(ctx, g.driver, anthrovePostID, anthroveSourceDomain, anthrovePostRelationship) } func (g *graphConnection) LinkUserWithPost(ctx context.Context, anthroveUser *models.AnthroveUser, anthrovePost *models.AnthrovePost) error { - return internal.EstablishUserToPostLink(ctx, g.driver, anthroveUser, anthrovePost) + return graph.EstablishUserToPostLink(ctx, g.driver, anthroveUser, anthrovePost) } func (g *graphConnection) CheckUserPostLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) { - return internal.CheckUserToPostLink(ctx, g.driver, anthroveUserID, sourcePostID, sourceUrl) + return graph.CheckUserToPostLink(ctx, g.driver, anthroveUserID, sourcePostID, sourceUrl) } func (g *graphConnection) CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *models.AnthrovePost) (*models.AnthrovePost, bool, error) { - return internal.CheckIfAnthrovePostNodeExistsByAnthroveID(ctx, g.driver, anthrovePost) + return graph.CheckIfAnthrovePostNodeExistsByAnthroveID(ctx, g.driver, anthrovePost) } func (g *graphConnection) CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*models.AnthrovePost, bool, error) { - return internal.CheckIfAnthrovePostNodeExistsBySourceURl(ctx, g.driver, sourceUrl) + return graph.CheckIfAnthrovePostNodeExistsBySourceURl(ctx, g.driver, sourceUrl) } func (g *graphConnection) CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*models.AnthrovePost, bool, error) { - return internal.CheckIfAnthrovePostNodeExistsBySourceID(ctx, g.driver, sourcePostID) + return graph.CheckIfAnthrovePostNodeExistsBySourceID(ctx, g.driver, sourcePostID) } func (g *graphConnection) GetUserFavoriteCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) { - return internal.GetUserFavoritesCount(ctx, g.driver, anthroveUserID) + return graph.GetUserFavoritesCount(ctx, g.driver, anthroveUserID) } func (g *graphConnection) GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.AnthroveUserRelationship, error) { - return internal.GetUserSourceLink(ctx, g.driver, anthroveUserID) + return graph.GetUserSourceLink(ctx, g.driver, anthroveUserID) } func (g *graphConnection) GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.AnthroveUserRelationship, error) { - return internal.GetSpecifiedUserSourceLink(ctx, g.driver, anthroveUserID, sourceDisplayName) + return graph.GetSpecifiedUserSourceLink(ctx, g.driver, anthroveUserID, sourceDisplayName) } func (g *graphConnection) GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*models.AnthroveUser, error) { - return internal.GetAnthroveUser(ctx, g.driver, anthroveUserID) + return graph.GetAnthroveUser(ctx, g.driver, anthroveUserID) } func (g *graphConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) { - return internal.GetAllAnthroveUserIDs(ctx, g.driver) + return graph.GetAllAnthroveUserIDs(ctx, g.driver) } func (g *graphConnection) GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) { - return internal.GetUserFavoriteNodeWithPagination(ctx, g.driver, anthroveUserID, skip, limit) + return graph.GetUserFavoriteNodeWithPagination(ctx, g.driver, anthroveUserID, skip, limit) } func (g *graphConnection) GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { - return internal.GetUserTagNodeWitRelationToFavedPosts(ctx, g.driver, anthroveUserID) + return graph.GetUserTagNodeWitRelationToFavedPosts(ctx, g.driver, anthroveUserID) } func (g *graphConnection) GetAllTags(ctx context.Context) ([]models.TagsWithFrequency, error) { - return internal.GetTags(ctx, g.driver) + return graph.GetTags(ctx, g.driver) } func (g *graphConnection) GetAllSources(ctx context.Context) ([]models.AnthroveSource, error) { - return internal.GetAllSourceNodes(ctx, g.driver) + return graph.GetAllSourceNodes(ctx, g.driver) } func (g *graphConnection) GetSourceByURL(ctx context.Context, sourceUrl string) (*models.AnthroveSource, error) { - return internal.GetSourceNodesByURL(ctx, g.driver, sourceUrl) + return graph.GetSourceNodesByURL(ctx, g.driver, sourceUrl) } func logger(graphDebug bool) func(config *config.Config) { return func(config *config.Config) { - config.Log = internal.NewGraphLogger(graphDebug) + config.Log = graph.NewGraphLogger(graphDebug) } } -- 2.45.1 From 0d5274eb27ed14c7443ac8172f193cfe4257accb Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 3 Jun 2024 21:31:44 +0200 Subject: [PATCH 003/124] feat: connecting to postgres now possible Signed-off-by: SoXX --- go.mod | 10 ++- go.sum | 22 +++++- pkg/database/database.go | 2 +- pkg/database/graph_impl.go | 2 +- pkg/database/postgresql_impl.go | 130 ++++++++++++++++++++++++++++++++ 5 files changed, 159 insertions(+), 7 deletions(-) create mode 100644 pkg/database/postgresql_impl.go diff --git a/go.mod b/go.mod index 37b8e64..dc9cdf6 100644 --- a/go.mod +++ b/go.mod @@ -5,11 +5,17 @@ go 1.22.0 require ( github.com/neo4j/neo4j-go-driver/v5 v5.17.0 github.com/sirupsen/logrus v1.9.3 + gorm.io/driver/postgres v1.5.7 + gorm.io/gorm v1.25.10 ) require ( + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgx/v5 v5.4.3 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect - gorm.io/gorm v1.25.10 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect ) diff --git a/go.sum b/go.sum index a7307ff..2c77d3a 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,12 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY= +github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= @@ -12,12 +18,22 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM= +gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA= gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= diff --git a/pkg/database/database.go b/pkg/database/database.go index 867e72a..62f3158 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -37,7 +37,7 @@ import ( type OtterSpace interface { // Connect sets up a connection to the OtterSpace API endpoint using the provided username and password. // It returns an error if the connection cannot be established. - Connect(ctx context.Context, endpoint string, username string, password string) error + Connect(ctx context.Context, endpoint string, username string, password string, database string, port int, ssl string, timezone string) error // AddUserWithRelationToSource adds a new user to the OtterSpace database and associates them with a source. // It returns the newly created user and an error if the operation fails. diff --git a/pkg/database/graph_impl.go b/pkg/database/graph_impl.go index fac6a85..a48fad6 100644 --- a/pkg/database/graph_impl.go +++ b/pkg/database/graph_impl.go @@ -21,7 +21,7 @@ func NewGraphConnection(graphDebug bool) OtterSpace { } } -func (g *graphConnection) Connect(ctx context.Context, endpoint string, username string, password string) error { +func (g *graphConnection) Connect(ctx context.Context, endpoint string, username string, password string, _ string, _ int, _ string, _ string) error { driver, err := neo4j.NewDriverWithContext(endpoint, neo4j.BasicAuth(username, password, ""), logger(g.graphDebug)) diff --git a/pkg/database/postgresql_impl.go b/pkg/database/postgresql_impl.go new file mode 100644 index 0000000..96e241f --- /dev/null +++ b/pkg/database/postgresql_impl.go @@ -0,0 +1,130 @@ +package database + +import ( + "context" + "fmt" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "gorm.io/driver/postgres" + "gorm.io/gorm" +) + +type postgresqlConnection struct { + db *gorm.DB +} + +func NewPostgresqlConnection() OtterSpace { + return &postgresqlConnection{ + db: nil, + } +} + +func (p postgresqlConnection) Connect(ctx context.Context, endpoint string, username string, password string, database string, port int, ssl string, timezone string) error { + + dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s TimeZone=%s", endpoint, username, password, database, port, ssl, timezone) + db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) + p.db = db + if err != nil { + return err + } + return nil +} + +func (p postgresqlConnection) AddUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) AddSource(ctx context.Context, anthroveSource *models.AnthroveSource) error { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) AddPost(ctx context.Context, anthrovePost *models.AnthrovePost) error { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.AnthroveTag) error { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *models.AnthrovePostRelationship) error { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) LinkUserWithPost(ctx context.Context, anthroveUser *models.AnthroveUser, anthrovePost *models.AnthrovePost) error { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) CheckUserPostLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *models.AnthrovePost) (*models.AnthrovePost, bool, error) { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*models.AnthrovePost, bool, error) { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*models.AnthrovePost, bool, error) { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) GetUserFavoriteCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.AnthroveUserRelationship, error) { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.AnthroveUserRelationship, error) { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*models.AnthroveUser, error) { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) GetAllTags(ctx context.Context) ([]models.TagsWithFrequency, error) { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) GetAllSources(ctx context.Context) ([]models.AnthroveSource, error) { + //TODO implement me + panic("implement me") +} + +func (p postgresqlConnection) GetSourceByURL(ctx context.Context, sourceUrl string) (*models.AnthroveSource, error) { + //TODO implement me + panic("implement me") +} -- 2.45.1 From c1df01d11399a643a4eec6a9507e4e299bd3d898 Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 3 Jun 2024 21:45:39 +0200 Subject: [PATCH 004/124] chore: reorganizing code Signed-off-by: SoXX --- pkg/database/{graph_impl.go => graph/graph.go} | 5 +++-- pkg/database/{postgresql_impl.go => postgres/postgres.go} | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) rename pkg/database/{graph_impl.go => graph/graph.go} (97%) rename pkg/database/{postgresql_impl.go => postgres/postgres.go} (97%) diff --git a/pkg/database/graph_impl.go b/pkg/database/graph/graph.go similarity index 97% rename from pkg/database/graph_impl.go rename to pkg/database/graph/graph.go index a48fad6..81f94a8 100644 --- a/pkg/database/graph_impl.go +++ b/pkg/database/graph/graph.go @@ -1,8 +1,9 @@ -package database +package graph import ( "context" "git.dragse.it/anthrove/otter-space-sdk/internal/graph" + "git.dragse.it/anthrove/otter-space-sdk/pkg/database" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "github.com/neo4j/neo4j-go-driver/v5/neo4j" @@ -14,7 +15,7 @@ type graphConnection struct { graphDebug bool } -func NewGraphConnection(graphDebug bool) OtterSpace { +func NewGraphConnection(graphDebug bool) database.OtterSpace { return &graphConnection{ driver: nil, graphDebug: graphDebug, diff --git a/pkg/database/postgresql_impl.go b/pkg/database/postgres/postgres.go similarity index 97% rename from pkg/database/postgresql_impl.go rename to pkg/database/postgres/postgres.go index 96e241f..bac144a 100644 --- a/pkg/database/postgresql_impl.go +++ b/pkg/database/postgres/postgres.go @@ -1,8 +1,9 @@ -package database +package postgres import ( "context" "fmt" + "git.dragse.it/anthrove/otter-space-sdk/pkg/database" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "gorm.io/driver/postgres" "gorm.io/gorm" @@ -12,7 +13,7 @@ type postgresqlConnection struct { db *gorm.DB } -func NewPostgresqlConnection() OtterSpace { +func NewPostgresqlConnection() database.OtterSpace { return &postgresqlConnection{ db: nil, } -- 2.45.1 From ebc7fcc571f0d1b629089a8884931ce309cafa53 Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 3 Jun 2024 22:14:50 +0200 Subject: [PATCH 005/124] feat(sources): get all source nodes Signed-off-by: SoXX --- internal/postgres/source.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 internal/postgres/source.go diff --git a/internal/postgres/source.go b/internal/postgres/source.go new file mode 100644 index 0000000..6871f45 --- /dev/null +++ b/internal/postgres/source.go @@ -0,0 +1,25 @@ +package postgres + +import ( + "context" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + log "github.com/sirupsen/logrus" + "gorm.io/gorm" +) + +// GetAllSourceNodes returns a list of all models.AnthroveSource +func GetAllSourceNodes(ctx context.Context, db *gorm.DB) ([]models.AnthroveSource, error) { + var sources []models.AnthroveSource + + result := db.WithContext(ctx).Find(&sources) + + if result.Error != nil { + return nil, result.Error + } + + log.WithFields(log.Fields{ + "tag_amount": result.RowsAffected, + }).Trace("database: get all source nodes") + + return sources, nil +} -- 2.45.1 From ea2958b27d406cc4b3f19914bb7a1e98c2696440 Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 3 Jun 2024 22:18:02 +0200 Subject: [PATCH 006/124] feat(sources): finished implementing get all sources Signed-off-by: SoXX --- pkg/database/{graph => }/graph.go | 6 ++---- pkg/database/{postgres => }/postgres.go | 13 ++++++------- 2 files changed, 8 insertions(+), 11 deletions(-) rename pkg/database/{graph => }/graph.go (97%) rename pkg/database/{postgres => }/postgres.go (94%) diff --git a/pkg/database/graph/graph.go b/pkg/database/graph.go similarity index 97% rename from pkg/database/graph/graph.go rename to pkg/database/graph.go index 81f94a8..869f643 100644 --- a/pkg/database/graph/graph.go +++ b/pkg/database/graph.go @@ -1,10 +1,8 @@ -package graph +package database import ( "context" "git.dragse.it/anthrove/otter-space-sdk/internal/graph" - "git.dragse.it/anthrove/otter-space-sdk/pkg/database" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "github.com/neo4j/neo4j-go-driver/v5/neo4j" "github.com/neo4j/neo4j-go-driver/v5/neo4j/config" @@ -15,7 +13,7 @@ type graphConnection struct { graphDebug bool } -func NewGraphConnection(graphDebug bool) database.OtterSpace { +func NewGraphConnection(graphDebug bool) OtterSpace { return &graphConnection{ driver: nil, graphDebug: graphDebug, diff --git a/pkg/database/postgres/postgres.go b/pkg/database/postgres.go similarity index 94% rename from pkg/database/postgres/postgres.go rename to pkg/database/postgres.go index bac144a..89628e6 100644 --- a/pkg/database/postgres/postgres.go +++ b/pkg/database/postgres.go @@ -1,11 +1,11 @@ -package postgres +package database import ( "context" "fmt" - "git.dragse.it/anthrove/otter-space-sdk/pkg/database" + "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "gorm.io/driver/postgres" + gormPostgres "gorm.io/driver/postgres" "gorm.io/gorm" ) @@ -13,7 +13,7 @@ type postgresqlConnection struct { db *gorm.DB } -func NewPostgresqlConnection() database.OtterSpace { +func NewPostgresqlConnection() OtterSpace { return &postgresqlConnection{ db: nil, } @@ -22,7 +22,7 @@ func NewPostgresqlConnection() database.OtterSpace { func (p postgresqlConnection) Connect(ctx context.Context, endpoint string, username string, password string, database string, port int, ssl string, timezone string) error { dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s TimeZone=%s", endpoint, username, password, database, port, ssl, timezone) - db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) + db, err := gorm.Open(gormPostgres.Open(dsn), &gorm.Config{}) p.db = db if err != nil { return err @@ -121,8 +121,7 @@ func (p postgresqlConnection) GetAllTags(ctx context.Context) ([]models.TagsWith } func (p postgresqlConnection) GetAllSources(ctx context.Context) ([]models.AnthroveSource, error) { - //TODO implement me - panic("implement me") + return postgres.GetAllSourceNodes(ctx, p.db) } func (p postgresqlConnection) GetSourceByURL(ctx context.Context, sourceUrl string) (*models.AnthroveSource, error) { -- 2.45.1 From 21b43333d068b39f5576547f96796945d3371c0e Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 3 Jun 2024 23:55:30 +0200 Subject: [PATCH 007/124] feat(sources): restructure models and first implementation of pgModel Signed-off-by: SoXX --- internal/graph/post.go | 14 +-- internal/graph/relationships.go | 6 +- internal/graph/source.go | 14 +-- internal/graph/tag.go | 12 +-- internal/graph/user.go | 64 +++++++------- internal/postgres/source.go | 6 +- pkg/database/database.go | 34 ++++---- pkg/database/graph.go | 33 +++---- pkg/database/postgres.go | 33 +++---- pkg/models/README.md | 87 +++++++++++++++++++ pkg/models/const.go | 23 +++-- pkg/models/{ => graphModels}/api.go | 2 +- pkg/models/graphModels/post.go | 8 ++ pkg/models/{ => graphModels}/relationships.go | 2 +- pkg/models/{ => graphModels}/source.go | 2 +- pkg/models/{ => graphModels}/tag.go | 2 +- pkg/models/graphModels/user.go | 8 ++ pkg/models/pgModels/orm.go | 13 +++ pkg/models/pgModels/post.go | 14 +++ pkg/models/pgModels/source.go | 8 ++ pkg/models/pgModels/tag.go | 21 +++++ pkg/models/pgModels/user.go | 6 ++ pkg/models/post.go | 6 -- pkg/models/user.go | 6 -- 24 files changed, 295 insertions(+), 129 deletions(-) create mode 100644 pkg/models/README.md rename pkg/models/{ => graphModels}/api.go (95%) create mode 100644 pkg/models/graphModels/post.go rename pkg/models/{ => graphModels}/relationships.go (94%) rename pkg/models/{ => graphModels}/source.go (87%) rename pkg/models/{ => graphModels}/tag.go (80%) create mode 100644 pkg/models/graphModels/user.go create mode 100644 pkg/models/pgModels/orm.go create mode 100644 pkg/models/pgModels/post.go create mode 100644 pkg/models/pgModels/source.go create mode 100644 pkg/models/pgModels/tag.go create mode 100644 pkg/models/pgModels/user.go delete mode 100644 pkg/models/post.go delete mode 100644 pkg/models/user.go diff --git a/internal/graph/post.go b/internal/graph/post.go index 6a39f51..d263928 100644 --- a/internal/graph/post.go +++ b/internal/graph/post.go @@ -2,13 +2,13 @@ package graph import ( "context" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" "github.com/neo4j/neo4j-go-driver/v5/neo4j" log "github.com/sirupsen/logrus" ) -func CreateAnthrovePostNode(ctx context.Context, driver neo4j.DriverWithContext, anthrovePost *models.AnthrovePost) error { +func CreateAnthrovePostNode(ctx context.Context, driver neo4j.DriverWithContext, anthrovePost *graphModels.AnthrovePost) error { query := ` CREATE (newPostNode:AnthrovePost {post_id: $anthrove_post_id, rating: $anthrove_rating}) ` @@ -31,7 +31,7 @@ func CreateAnthrovePostNode(ctx context.Context, driver neo4j.DriverWithContext, return nil } -func CheckIfAnthrovePostNodeExistsByAnthroveID(ctx context.Context, driver neo4j.DriverWithContext, anthrovePost *models.AnthrovePost) (*models.AnthrovePost, bool, error) { +func CheckIfAnthrovePostNodeExistsByAnthroveID(ctx context.Context, driver neo4j.DriverWithContext, anthrovePost *graphModels.AnthrovePost) (*graphModels.AnthrovePost, bool, error) { query := ` OPTIONAL MATCH (postNode:AnthrovePost {post_id: $anthrove_post_id}) RETURN postNode.post_id AS AnthrovePostID @@ -49,7 +49,7 @@ func CheckIfAnthrovePostNodeExistsByAnthroveID(ctx context.Context, driver neo4j return anthrovePost, exists, nil } -func CheckIfAnthrovePostNodeExistsBySourceURl(ctx context.Context, driver neo4j.DriverWithContext, sourceUrl string) (*models.AnthrovePost, bool, error) { +func CheckIfAnthrovePostNodeExistsBySourceURl(ctx context.Context, driver neo4j.DriverWithContext, sourceUrl string) (*graphModels.AnthrovePost, bool, error) { query := ` OPTIONAL MATCH (postNode:AnthrovePost)<-[:REFERENCE {url: $source_url}]-() RETURN postNode.post_id AS AnthrovePostID @@ -66,7 +66,7 @@ func CheckIfAnthrovePostNodeExistsBySourceURl(ctx context.Context, driver neo4j. return anthrovePost, exists, nil } -func CheckIfAnthrovePostNodeExistsBySourceID(ctx context.Context, driver neo4j.DriverWithContext, sourcePostID string) (*models.AnthrovePost, bool, error) { +func CheckIfAnthrovePostNodeExistsBySourceID(ctx context.Context, driver neo4j.DriverWithContext, sourcePostID string) (*graphModels.AnthrovePost, bool, error) { query := ` OPTIONAL MATCH (postNode:AnthrovePost)<-[:REFERENCE {source_post_id: $source_post_id}]-() RETURN postNode.post_id AS AnthrovePostID @@ -84,9 +84,9 @@ func CheckIfAnthrovePostNodeExistsBySourceID(ctx context.Context, driver neo4j.D return anthrovePost, exists, nil } -func executeCheckQuery(ctx context.Context, driver neo4j.DriverWithContext, query string, params map[string]any) (*models.AnthrovePost, bool, error) { +func executeCheckQuery(ctx context.Context, driver neo4j.DriverWithContext, query string, params map[string]any) (*graphModels.AnthrovePost, bool, error) { - var anthrovePost models.AnthrovePost + var anthrovePost graphModels.AnthrovePost result, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) if err != nil { diff --git a/internal/graph/relationships.go b/internal/graph/relationships.go index b77c8e6..d9ea521 100644 --- a/internal/graph/relationships.go +++ b/internal/graph/relationships.go @@ -3,13 +3,13 @@ package graph import ( "context" "fmt" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" "github.com/neo4j/neo4j-go-driver/v5/neo4j" log "github.com/sirupsen/logrus" ) -func EstablishAnthrovePostToSourceLink(ctx context.Context, driver neo4j.DriverWithContext, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *models.AnthrovePostRelationship) error { +func EstablishAnthrovePostToSourceLink(ctx context.Context, driver neo4j.DriverWithContext, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error { query := ` MATCH (sourceNode:Source {domain: $source_url}) MATCH (postNode:AnthrovePost {post_id: $anthrove_post_id}) @@ -38,7 +38,7 @@ func EstablishAnthrovePostToSourceLink(ctx context.Context, driver neo4j.DriverW return nil } -func EstablishUserToPostLink(ctx context.Context, driver neo4j.DriverWithContext, anthroveUser *models.AnthroveUser, anthrovePost *models.AnthrovePost) error { +func EstablishUserToPostLink(ctx context.Context, driver neo4j.DriverWithContext, anthroveUser *graphModels.AnthroveUser, anthrovePost *graphModels.AnthrovePost) error { query := ` MATCH (user:User {user_id: $anthrove_user_id}) diff --git a/internal/graph/source.go b/internal/graph/source.go index cbdc690..5ed8fa6 100644 --- a/internal/graph/source.go +++ b/internal/graph/source.go @@ -3,13 +3,13 @@ package graph import ( "context" "fmt" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "github.com/neo4j/neo4j-go-driver/v5/neo4j" log "github.com/sirupsen/logrus" ) -func CreateSourceNode(ctx context.Context, driver neo4j.DriverWithContext, anthroveSource *models.AnthroveSource) error { +func CreateSourceNode(ctx context.Context, driver neo4j.DriverWithContext, anthroveSource *graphModels.AnthroveSource) error { query := ` MERGE (sourceNode:Source {domain: $source_url}) ON CREATE SET sourceNode.domain = $source_url, sourceNode.display_name = $source_display_name, sourceNode.icon = $source_icon @@ -34,8 +34,8 @@ func CreateSourceNode(ctx context.Context, driver neo4j.DriverWithContext, anthr return nil } -func GetAllSourceNodes(ctx context.Context, driver neo4j.DriverWithContext) ([]models.AnthroveSource, error) { - var sources []models.AnthroveSource +func GetAllSourceNodes(ctx context.Context, driver neo4j.DriverWithContext) ([]graphModels.AnthroveSource, error) { + var sources []graphModels.AnthroveSource query := ` MATCH (s:Source) @@ -60,7 +60,7 @@ func GetAllSourceNodes(ctx context.Context, driver neo4j.DriverWithContext) ([]m return nil, err } - sources = append(sources, models.AnthroveSource{ + sources = append(sources, graphModels.AnthroveSource{ DisplayName: source.Props["display_name"].(string), Domain: source.Props["domain"].(string), Icon: source.Props["icon"].(string), @@ -75,9 +75,9 @@ func GetAllSourceNodes(ctx context.Context, driver neo4j.DriverWithContext) ([]m return sources, nil } -func GetSourceNodesByURL(ctx context.Context, driver neo4j.DriverWithContext, sourceUrl string) (*models.AnthroveSource, error) { +func GetSourceNodesByURL(ctx context.Context, driver neo4j.DriverWithContext, sourceUrl string) (*graphModels.AnthroveSource, error) { - var source models.AnthroveSource + var source graphModels.AnthroveSource query := ` MATCH (s:Source {domain: $source_url}) diff --git a/internal/graph/tag.go b/internal/graph/tag.go index 0838b13..cc9142c 100644 --- a/internal/graph/tag.go +++ b/internal/graph/tag.go @@ -2,13 +2,13 @@ package graph import ( "context" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" "github.com/neo4j/neo4j-go-driver/v5/neo4j" log "github.com/sirupsen/logrus" ) -func CreateTagNodeWitRelation(ctx context.Context, driver neo4j.DriverWithContext, anthrovePostID models.AnthrovePostID, anthroveTag *models.AnthroveTag) error { +func CreateTagNodeWitRelation(ctx context.Context, driver neo4j.DriverWithContext, anthrovePostID models.AnthrovePostID, anthroveTag *graphModels.AnthroveTag) error { query := ` MATCH (anthrovePost:AnthrovePost {post_id: $anthrove_post_id}) MERGE (tagNode:Tag {name: $tag_name, type: $tag_type}) @@ -34,8 +34,8 @@ func CreateTagNodeWitRelation(ctx context.Context, driver neo4j.DriverWithContex return nil } -func GetTags(ctx context.Context, driver neo4j.DriverWithContext) ([]models.TagsWithFrequency, error) { - var userTags []models.TagsWithFrequency +func GetTags(ctx context.Context, driver neo4j.DriverWithContext) ([]graphModels.TagsWithFrequency, error) { + var userTags []graphModels.TagsWithFrequency query := ` MATCH (:AnthrovePost)-[:HAS]->(t:Tag) @@ -66,9 +66,9 @@ func GetTags(ctx context.Context, driver neo4j.DriverWithContext) ([]models.Tags return nil, err } - userTags = append(userTags, models.TagsWithFrequency{ + userTags = append(userTags, graphModels.TagsWithFrequency{ Frequency: frequency, - Tags: models.AnthroveTag{ + Tags: graphModels.AnthroveTag{ Name: tag.Props["name"].(string), Type: tag.Props["type"].(string), }, diff --git a/internal/graph/user.go b/internal/graph/user.go index 7d4a8e8..a136de3 100644 --- a/internal/graph/user.go +++ b/internal/graph/user.go @@ -3,9 +3,9 @@ package graph import ( "context" "fmt" - "git.dragse.it/anthrove/otter-space-sdk/internal/utils" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" "github.com/neo4j/neo4j-go-driver/v5/neo4j" log "github.com/sirupsen/logrus" ) @@ -28,13 +28,13 @@ func CreateUserNodeWithSourceRelation(ctx context.Context, driver neo4j.DriverWi return err } - var anthroveUserRelationship []models.AnthroveUserRelationship + var anthroveUserRelationship []graphModels.AnthroveUserRelationship - anthroveUserRelationship = append(anthroveUserRelationship, models.AnthroveUserRelationship{ + anthroveUserRelationship = append(anthroveUserRelationship, graphModels.AnthroveUserRelationship{ UserID: userID, Username: username, ScrapeTimeInterval: "", - Source: models.AnthroveSource{ + Source: graphModels.AnthroveSource{ DisplayName: "", Domain: sourceDomain, Icon: "", @@ -90,9 +90,9 @@ func GetUserFavoritesCount(ctx context.Context, driver neo4j.DriverWithContext, return userFavoriteCount, nil } -func GetUserSourceLink(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID) (map[string]models.AnthroveUserRelationship, error) { +func GetUserSourceLink(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID) (map[string]graphModels.AnthroveUserRelationship, error) { - userSource := make(map[string]models.AnthroveUserRelationship) + userSource := make(map[string]graphModels.AnthroveUserRelationship) query := ` MATCH (user:User{user_id: $anthrove_user_id})-[r:HAS_ACCOUNT_AT]->(s:Source) @@ -130,10 +130,10 @@ func GetUserSourceLink(ctx context.Context, driver neo4j.DriverWithContext, anth domain := source.Props["domain"].(string) icon := source.Props["icon"].(string) - anthroveSourceUser := models.AnthroveUserRelationship{ + anthroveSourceUser := graphModels.AnthroveUserRelationship{ UserID: sourceUserID, Username: sourceUsername, - Source: models.AnthroveSource{ + Source: graphModels.AnthroveSource{ DisplayName: displayName, Domain: domain, Icon: icon, @@ -150,9 +150,9 @@ func GetUserSourceLink(ctx context.Context, driver neo4j.DriverWithContext, anth return userSource, nil } -func GetSpecifiedUserSourceLink(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.AnthroveUserRelationship, error) { +func GetSpecifiedUserSourceLink(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]graphModels.AnthroveUserRelationship, error) { - userSource := make(map[string]models.AnthroveUserRelationship) + userSource := make(map[string]graphModels.AnthroveUserRelationship) query := ` MATCH (user:User{user_id: $anthrove_user_id})-[r:HAS_ACCOUNT_AT]->(s:Source{display_name: $source_display_name}) @@ -191,10 +191,10 @@ func GetSpecifiedUserSourceLink(ctx context.Context, driver neo4j.DriverWithCont domain := source.Props["domain"].(string) icon := source.Props["icon"].(string) - anthroveSourceUser := models.AnthroveUserRelationship{ + anthroveSourceUser := graphModels.AnthroveUserRelationship{ UserID: sourceUserID, Username: sourceUsername, - Source: models.AnthroveSource{ + Source: graphModels.AnthroveSource{ DisplayName: displayName, Domain: domain, Icon: icon, @@ -211,11 +211,11 @@ func GetSpecifiedUserSourceLink(ctx context.Context, driver neo4j.DriverWithCont return userSource, nil } -func GetAnthroveUser(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID) (*models.AnthroveUser, error) { +func GetAnthroveUser(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID) (*graphModels.AnthroveUser, error) { var err error - var anthroveUser models.AnthroveUser - var userSources models.AnthroveSource - userRelationships := make([]models.AnthroveUserRelationship, 0) + var anthroveUser graphModels.AnthroveUser + var userSources graphModels.AnthroveSource + userRelationships := make([]graphModels.AnthroveUserRelationship, 0) query := ` MATCH (user:User{user_id: $anthrove_user_id})-[relation:HAS_ACCOUNT_AT]->(source:Source) @@ -250,13 +250,13 @@ func GetAnthroveUser(ctx context.Context, driver neo4j.DriverWithContext, anthro return nil, err } - userRelationships = append(userRelationships, models.AnthroveUserRelationship{ + userRelationships = append(userRelationships, graphModels.AnthroveUserRelationship{ UserID: fmt.Sprintf("%v", utils.GetOrDefault(relation.Props, "user_id", "")), Username: utils.GetOrDefault(relation.Props, "username", "").(string), ScrapeTimeInterval: utils.GetOrDefault(relation.Props, "scrape_time_interval", "").(string), }) - userSources = models.AnthroveSource{ + userSources = graphModels.AnthroveSource{ DisplayName: utils.GetOrDefault(source.Props, "display_name", "").(string), Domain: utils.GetOrDefault(source.Props, "domain", "").(string), Icon: utils.GetOrDefault(source.Props, "icon", "").(string), @@ -316,9 +316,9 @@ func GetAllAnthroveUserIDs(ctx context.Context, driver neo4j.DriverWithContext) } -func GetUserFavoriteNodeWithPagination(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) { +func GetUserFavoriteNodeWithPagination(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID, skip int, limit int) (*graphModels.FavoriteList, error) { var err error - var favoritePosts []models.FavoritePost + var favoritePosts []graphModels.FavoritePost query := ` CALL { @@ -368,22 +368,22 @@ func GetUserFavoriteNodeWithPagination(ctx context.Context, driver neo4j.DriverW } if len(favoritePosts) != 0 && favoritePosts[len(favoritePosts)-1].AnthrovePost.PostID == models.AnthrovePostID(anthrovePost.Props["post_id"].(string)) { - favoritePosts[len(favoritePosts)-1].Relations = append(favoritePosts[len(favoritePosts)-1].Relations, models.FavoriteRelations{ + favoritePosts[len(favoritePosts)-1].Relations = append(favoritePosts[len(favoritePosts)-1].Relations, graphModels.FavoriteRelations{ SourcesID: source.Props["display_name"].(string), - Relations: models.AnthrovePostRelationship{ + Relations: graphModels.AnthrovePostRelationship{ PostID: postRelation.Props["source_post_id"].(string), Url: postRelation.Props["url"].(string), }, }) } else { - favoritePosts = append(favoritePosts, models.FavoritePost{ - AnthrovePost: models.AnthrovePost{ + favoritePosts = append(favoritePosts, graphModels.FavoritePost{ + AnthrovePost: graphModels.AnthrovePost{ PostID: models.AnthrovePostID(anthrovePost.Props["post_id"].(string)), - Rating: models.AnthroveRating(anthrovePost.Props["rating"].(string)), + Rating: models.Rating(anthrovePost.Props["rating"].(string)), }, - Relations: []models.FavoriteRelations{{ + Relations: []graphModels.FavoriteRelations{{ SourcesID: source.Props["display_name"].(string), - Relations: models.AnthrovePostRelationship{ + Relations: graphModels.AnthrovePostRelationship{ PostID: postRelation.Props["source_post_id"].(string), Url: postRelation.Props["url"].(string), }, @@ -398,12 +398,12 @@ func GetUserFavoriteNodeWithPagination(ctx context.Context, driver neo4j.DriverW "anthrove_user_fav_count": len(favoritePosts), }).Trace("database: got al anthrove user favorites") - return &models.FavoriteList{Posts: favoritePosts}, nil + return &graphModels.FavoriteList{Posts: favoritePosts}, nil } -func GetUserTagNodeWitRelationToFavedPosts(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { - var userTags []models.TagsWithFrequency +func GetUserTagNodeWitRelationToFavedPosts(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID) ([]graphModels.TagsWithFrequency, error) { + var userTags []graphModels.TagsWithFrequency query := ` MATCH (u:User {user_id: $anthrove_user_id})-[:FAV]->(:AnthrovePost)-[:HAS]->(t:Tag) @@ -436,9 +436,9 @@ func GetUserTagNodeWitRelationToFavedPosts(ctx context.Context, driver neo4j.Dri return nil, err } - userTags = append(userTags, models.TagsWithFrequency{ + userTags = append(userTags, graphModels.TagsWithFrequency{ Frequency: frequency, - Tags: models.AnthroveTag{ + Tags: graphModels.AnthroveTag{ Name: tag.Props["name"].(string), Type: tag.Props["type"].(string), }, diff --git a/internal/postgres/source.go b/internal/postgres/source.go index 6871f45..956c53b 100644 --- a/internal/postgres/source.go +++ b/internal/postgres/source.go @@ -2,14 +2,14 @@ package postgres import ( "context" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) // GetAllSourceNodes returns a list of all models.AnthroveSource -func GetAllSourceNodes(ctx context.Context, db *gorm.DB) ([]models.AnthroveSource, error) { - var sources []models.AnthroveSource +func GetAllSourceNodes(ctx context.Context, db *gorm.DB) ([]graphModels.AnthroveSource, error) { + var sources []graphModels.AnthroveSource result := db.WithContext(ctx).Find(&sources) diff --git a/pkg/database/database.go b/pkg/database/database.go index 62f3158..307bc83 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -27,8 +27,8 @@ package database import ( "context" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" ) // OtterSpace provides an interface for interacting with the OtterSpace API. @@ -45,23 +45,23 @@ type OtterSpace interface { // AddSource adds a new source to the OtterSpace database. // It returns an error if the operation fails. - AddSource(ctx context.Context, anthroveSource *models.AnthroveSource) error + AddSource(ctx context.Context, anthroveSource *graphModels.AnthroveSource) error // AddPost adds a new post to the OtterSpace database. // It returns an error if the operation fails. - AddPost(ctx context.Context, anthrovePost *models.AnthrovePost) error + AddPost(ctx context.Context, anthrovePost *graphModels.AnthrovePost) error // AddTagWithRelationToPost adds a new tag to the OtterSpace database and associates it with a post. // It returns an error if the operation fails. - AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.AnthroveTag) error + AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *graphModels.AnthroveTag) error // LinkPostWithSource establishes a link between a post and a source in the OtterSpace database. // It returns an error if the operation fails. - LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *models.AnthrovePostRelationship) error + LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error // LinkUserWithPost establishes a link between a user and a post in the OtterSpace database. // It returns an error if the operation fails. - LinkUserWithPost(ctx context.Context, anthroveUser *models.AnthroveUser, anthrovePost *models.AnthrovePost) error + LinkUserWithPost(ctx context.Context, anthroveUser *graphModels.AnthroveUser, anthrovePost *graphModels.AnthrovePost) error // CheckUserPostLink checks if a link between a user and a post exists in the OtterSpace database. // It returns true if the link exists, false otherwise, and an error if the operation fails. @@ -69,15 +69,15 @@ type OtterSpace interface { // CheckPostNodeExistsByAnthroveID checks if a post node exists in the OtterSpace database by its Anthrove ID. // It returns the post if it exists, a boolean indicating whether the post was found, and an error if the operation fails. - CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *models.AnthrovePost) (*models.AnthrovePost, bool, error) + CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *graphModels.AnthrovePost) (*graphModels.AnthrovePost, bool, error) // CheckPostNodeExistsBySourceURL checks if a post node exists in the OtterSpace database by its source URL. // It returns the post if it exists, a boolean indicating whether the post was found, and an error if the operation fails. - CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*models.AnthrovePost, bool, error) + CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*graphModels.AnthrovePost, bool, error) // CheckPostNodeExistsBySourceID checks if a post node exists in the OtterSpace database by its source ID. // It returns the post if it exists, a boolean indicating whether the post was found, and an error if the operation fails. - CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*models.AnthrovePost, bool, error) + CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*graphModels.AnthrovePost, bool, error) // GetUserFavoriteCount retrieves the count of a user's favorite posts from the OtterSpace database. // It returns the count and an error if the operation fails. @@ -85,32 +85,32 @@ type OtterSpace interface { // GetUserSourceLinks retrieves the links between a user and sources in the OtterSpace database. // It returns a map of source domains to user-source relationships, and an error if the operation fails. - GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.AnthroveUserRelationship, error) + GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]graphModels.AnthroveUserRelationship, error) // GetSpecifiedUserSourceLink GetUserSourceLinks retrieves the links between a user and a specific source in the OtterSpace database. // It returns a map of source domains to user-source relationships, and an error if the operation fails. - GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.AnthroveUserRelationship, error) + GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]graphModels.AnthroveUserRelationship, error) // GetAnthroveUser retrieves a user from the OtterSpace database by their ID. // It returns the user and an error if the operation fails. - GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*models.AnthroveUser, error) + GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*graphModels.AnthroveUser, error) // GetAllAnthroveUserIDs retrieves all user IDs from the OtterSpace database. // It returns a slice of user IDs and an error if the operation fails. GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) // GetUserFavoritePostsWithPagination gets all user favorites with relation and sources for the given user - GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) + GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*graphModels.FavoriteList, error) // GetUserTagsTroughFavedPosts returns a list of Tags that the user hs favorites through a post - GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) + GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]graphModels.TagsWithFrequency, error) // GetAllTags returns a list of Tags that the user hs favorites through a post - GetAllTags(ctx context.Context) ([]models.TagsWithFrequency, error) + GetAllTags(ctx context.Context) ([]graphModels.TagsWithFrequency, error) // GetAllSources returns a list of Sources in the database - GetAllSources(ctx context.Context) ([]models.AnthroveSource, error) + GetAllSources(ctx context.Context) ([]graphModels.AnthroveSource, error) // GetSourceByURL returns the Source Node based on the URL - GetSourceByURL(ctx context.Context, sourceUrl string) (*models.AnthroveSource, error) + GetSourceByURL(ctx context.Context, sourceUrl string) (*graphModels.AnthroveSource, error) } diff --git a/pkg/database/graph.go b/pkg/database/graph.go index 869f643..7fc5bf2 100644 --- a/pkg/database/graph.go +++ b/pkg/database/graph.go @@ -4,6 +4,7 @@ import ( "context" "git.dragse.it/anthrove/otter-space-sdk/internal/graph" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" "github.com/neo4j/neo4j-go-driver/v5/neo4j" "github.com/neo4j/neo4j-go-driver/v5/neo4j/config" ) @@ -39,23 +40,23 @@ func (g *graphConnection) AddUserWithRelationToSource(ctx context.Context, anthr return graph.CreateUserNodeWithSourceRelation(ctx, g.driver, anthroveUserID, sourceDomain, userID, username) } -func (g *graphConnection) AddSource(ctx context.Context, anthroveSource *models.AnthroveSource) error { +func (g *graphConnection) AddSource(ctx context.Context, anthroveSource *graphModels.AnthroveSource) error { return graph.CreateSourceNode(ctx, g.driver, anthroveSource) } -func (g *graphConnection) AddPost(ctx context.Context, anthrovePost *models.AnthrovePost) error { +func (g *graphConnection) AddPost(ctx context.Context, anthrovePost *graphModels.AnthrovePost) error { return graph.CreateAnthrovePostNode(ctx, g.driver, anthrovePost) } -func (g *graphConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.AnthroveTag) error { +func (g *graphConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *graphModels.AnthroveTag) error { return graph.CreateTagNodeWitRelation(ctx, g.driver, anthrovePostID, anthroveTag) } -func (g *graphConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *models.AnthrovePostRelationship) error { +func (g *graphConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error { return graph.EstablishAnthrovePostToSourceLink(ctx, g.driver, anthrovePostID, anthroveSourceDomain, anthrovePostRelationship) } -func (g *graphConnection) LinkUserWithPost(ctx context.Context, anthroveUser *models.AnthroveUser, anthrovePost *models.AnthrovePost) error { +func (g *graphConnection) LinkUserWithPost(ctx context.Context, anthroveUser *graphModels.AnthroveUser, anthrovePost *graphModels.AnthrovePost) error { return graph.EstablishUserToPostLink(ctx, g.driver, anthroveUser, anthrovePost) } @@ -63,15 +64,15 @@ func (g *graphConnection) CheckUserPostLink(ctx context.Context, anthroveUserID return graph.CheckUserToPostLink(ctx, g.driver, anthroveUserID, sourcePostID, sourceUrl) } -func (g *graphConnection) CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *models.AnthrovePost) (*models.AnthrovePost, bool, error) { +func (g *graphConnection) CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *graphModels.AnthrovePost) (*graphModels.AnthrovePost, bool, error) { return graph.CheckIfAnthrovePostNodeExistsByAnthroveID(ctx, g.driver, anthrovePost) } -func (g *graphConnection) CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*models.AnthrovePost, bool, error) { +func (g *graphConnection) CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*graphModels.AnthrovePost, bool, error) { return graph.CheckIfAnthrovePostNodeExistsBySourceURl(ctx, g.driver, sourceUrl) } -func (g *graphConnection) CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*models.AnthrovePost, bool, error) { +func (g *graphConnection) CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*graphModels.AnthrovePost, bool, error) { return graph.CheckIfAnthrovePostNodeExistsBySourceID(ctx, g.driver, sourcePostID) } @@ -79,15 +80,15 @@ func (g *graphConnection) GetUserFavoriteCount(ctx context.Context, anthroveUser return graph.GetUserFavoritesCount(ctx, g.driver, anthroveUserID) } -func (g *graphConnection) GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.AnthroveUserRelationship, error) { +func (g *graphConnection) GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]graphModels.AnthroveUserRelationship, error) { return graph.GetUserSourceLink(ctx, g.driver, anthroveUserID) } -func (g *graphConnection) GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.AnthroveUserRelationship, error) { +func (g *graphConnection) GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]graphModels.AnthroveUserRelationship, error) { return graph.GetSpecifiedUserSourceLink(ctx, g.driver, anthroveUserID, sourceDisplayName) } -func (g *graphConnection) GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*models.AnthroveUser, error) { +func (g *graphConnection) GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*graphModels.AnthroveUser, error) { return graph.GetAnthroveUser(ctx, g.driver, anthroveUserID) } @@ -95,23 +96,23 @@ func (g *graphConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]models.A return graph.GetAllAnthroveUserIDs(ctx, g.driver) } -func (g *graphConnection) GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) { +func (g *graphConnection) GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*graphModels.FavoriteList, error) { return graph.GetUserFavoriteNodeWithPagination(ctx, g.driver, anthroveUserID, skip, limit) } -func (g *graphConnection) GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { +func (g *graphConnection) GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]graphModels.TagsWithFrequency, error) { return graph.GetUserTagNodeWitRelationToFavedPosts(ctx, g.driver, anthroveUserID) } -func (g *graphConnection) GetAllTags(ctx context.Context) ([]models.TagsWithFrequency, error) { +func (g *graphConnection) GetAllTags(ctx context.Context) ([]graphModels.TagsWithFrequency, error) { return graph.GetTags(ctx, g.driver) } -func (g *graphConnection) GetAllSources(ctx context.Context) ([]models.AnthroveSource, error) { +func (g *graphConnection) GetAllSources(ctx context.Context) ([]graphModels.AnthroveSource, error) { return graph.GetAllSourceNodes(ctx, g.driver) } -func (g *graphConnection) GetSourceByURL(ctx context.Context, sourceUrl string) (*models.AnthroveSource, error) { +func (g *graphConnection) GetSourceByURL(ctx context.Context, sourceUrl string) (*graphModels.AnthroveSource, error) { return graph.GetSourceNodesByURL(ctx, g.driver, sourceUrl) } diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 89628e6..afb0fac 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -5,6 +5,7 @@ import ( "fmt" "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" gormPostgres "gorm.io/driver/postgres" "gorm.io/gorm" ) @@ -35,27 +36,27 @@ func (p postgresqlConnection) AddUserWithRelationToSource(ctx context.Context, a panic("implement me") } -func (p postgresqlConnection) AddSource(ctx context.Context, anthroveSource *models.AnthroveSource) error { +func (p postgresqlConnection) AddSource(ctx context.Context, anthroveSource *graphModels.AnthroveSource) error { //TODO implement me panic("implement me") } -func (p postgresqlConnection) AddPost(ctx context.Context, anthrovePost *models.AnthrovePost) error { +func (p postgresqlConnection) AddPost(ctx context.Context, anthrovePost *graphModels.AnthrovePost) error { //TODO implement me panic("implement me") } -func (p postgresqlConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.AnthroveTag) error { +func (p postgresqlConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *graphModels.AnthroveTag) error { //TODO implement me panic("implement me") } -func (p postgresqlConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *models.AnthrovePostRelationship) error { +func (p postgresqlConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error { //TODO implement me panic("implement me") } -func (p postgresqlConnection) LinkUserWithPost(ctx context.Context, anthroveUser *models.AnthroveUser, anthrovePost *models.AnthrovePost) error { +func (p postgresqlConnection) LinkUserWithPost(ctx context.Context, anthroveUser *graphModels.AnthroveUser, anthrovePost *graphModels.AnthrovePost) error { //TODO implement me panic("implement me") } @@ -65,17 +66,17 @@ func (p postgresqlConnection) CheckUserPostLink(ctx context.Context, anthroveUse panic("implement me") } -func (p postgresqlConnection) CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *models.AnthrovePost) (*models.AnthrovePost, bool, error) { +func (p postgresqlConnection) CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *graphModels.AnthrovePost) (*graphModels.AnthrovePost, bool, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*models.AnthrovePost, bool, error) { +func (p postgresqlConnection) CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*graphModels.AnthrovePost, bool, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*models.AnthrovePost, bool, error) { +func (p postgresqlConnection) CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*graphModels.AnthrovePost, bool, error) { //TODO implement me panic("implement me") } @@ -85,17 +86,17 @@ func (p postgresqlConnection) GetUserFavoriteCount(ctx context.Context, anthrove panic("implement me") } -func (p postgresqlConnection) GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.AnthroveUserRelationship, error) { +func (p postgresqlConnection) GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]graphModels.AnthroveUserRelationship, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.AnthroveUserRelationship, error) { +func (p postgresqlConnection) GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]graphModels.AnthroveUserRelationship, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*models.AnthroveUser, error) { +func (p postgresqlConnection) GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*graphModels.AnthroveUser, error) { //TODO implement me panic("implement me") } @@ -105,26 +106,26 @@ func (p postgresqlConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]mode panic("implement me") } -func (p postgresqlConnection) GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) { +func (p postgresqlConnection) GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*graphModels.FavoriteList, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { +func (p postgresqlConnection) GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]graphModels.TagsWithFrequency, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) GetAllTags(ctx context.Context) ([]models.TagsWithFrequency, error) { +func (p postgresqlConnection) GetAllTags(ctx context.Context) ([]graphModels.TagsWithFrequency, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) GetAllSources(ctx context.Context) ([]models.AnthroveSource, error) { +func (p postgresqlConnection) GetAllSources(ctx context.Context) ([]graphModels.AnthroveSource, error) { return postgres.GetAllSourceNodes(ctx, p.db) } -func (p postgresqlConnection) GetSourceByURL(ctx context.Context, sourceUrl string) (*models.AnthroveSource, error) { +func (p postgresqlConnection) GetSourceByURL(ctx context.Context, sourceUrl string) (*graphModels.AnthroveSource, error) { //TODO implement me panic("implement me") } diff --git a/pkg/models/README.md b/pkg/models/README.md new file mode 100644 index 0000000..7c824d0 --- /dev/null +++ b/pkg/models/README.md @@ -0,0 +1,87 @@ +# Postgres + +https://www.dbdiagram.io/d + +```` +Table User { + id string [primary key] + created_at timestamp +} + +Table Post { + id varchar(25) [primary key] + rating Rating + body text [note: 'Content of the post'] + user_id integer + status post_status + created_at timestamp +} + +Enum Rating { + safe + questionable + explicit +} + +Table Source { + id varchar(25) [primary key] + display_name text + domain text [not null, unique] +} + +Table Tag { + name text [primary key] + type TagType +} + +Enum TagType { + general + species + character + artist + lore + meta + invalid +} + +Table TagAlias { + name text [primary key] + tag_id text +} + +Table TagGroup { + name text [primary key] + tag_id text +} + +Table UserFavorites { + user_id text [primary key] + post_id text [primary key] + created_at timestamp +} + +Table UserSource { + user_id text [primary key] + source_id text [primary key] + account_username text + account_id text +} + +Table PostReference { + post_id text [primary key] + source_id text [primary key] + url text [not null, unique] + source_post_id text +} + +Ref: Tag.name > TagAlias.tag_id +Ref: Tag.name > TagGroup.tag_id +Ref: Tag.name <> Post.id +Ref: UserFavorites.user_id > User.id +Ref: UserFavorites.post_id > Post.id +Ref: UserSource.user_id > User.id +Ref: UserSource.source_id > Source.id +Ref: PostReference.post_id > Post.id +Ref: PostReference.source_id > Source.id + +```` \ No newline at end of file diff --git a/pkg/models/const.go b/pkg/models/const.go index 9dd312e..552193d 100644 --- a/pkg/models/const.go +++ b/pkg/models/const.go @@ -2,16 +2,27 @@ package models type AnthroveUserID string type AnthrovePostID string -type AnthroveRating string +type Rating string +type TagType string const ( - SFW AnthroveRating = "s" - NSFW AnthroveRating = "e" - Questionable AnthroveRating = "q" - Unknown AnthroveRating = "unknown" + SFW Rating = "s" + NSFW Rating = "e" + Questionable Rating = "q" + Unknown Rating = "unknown" ) -func (r *AnthroveRating) Convert(e621Rating string) { +const ( + General TagType = "general" + Species TagType = "species" + Character TagType = "character" + Artist TagType = "artist" + Lore TagType = "lore" + Meta TagType = "meta" + Invalid TagType = "invalid" +) + +func (r *Rating) Convert(e621Rating string) { switch e621Rating { case "e": diff --git a/pkg/models/api.go b/pkg/models/graphModels/api.go similarity index 95% rename from pkg/models/api.go rename to pkg/models/graphModels/api.go index a30b955..7683097 100644 --- a/pkg/models/api.go +++ b/pkg/models/graphModels/api.go @@ -1,4 +1,4 @@ -package models +package graphModels type FavoriteRelations struct { SourcesID string `json:"sources_id"` diff --git a/pkg/models/graphModels/post.go b/pkg/models/graphModels/post.go new file mode 100644 index 0000000..28caa38 --- /dev/null +++ b/pkg/models/graphModels/post.go @@ -0,0 +1,8 @@ +package graphModels + +import "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + +type AnthrovePost struct { + PostID models.AnthrovePostID `json:"post_id"` + Rating models.Rating `json:"rating"` +} diff --git a/pkg/models/relationships.go b/pkg/models/graphModels/relationships.go similarity index 94% rename from pkg/models/relationships.go rename to pkg/models/graphModels/relationships.go index f62e134..639966f 100644 --- a/pkg/models/relationships.go +++ b/pkg/models/graphModels/relationships.go @@ -1,4 +1,4 @@ -package models +package graphModels type AnthroveUserRelationship struct { UserID string `json:"user_id"` diff --git a/pkg/models/source.go b/pkg/models/graphModels/source.go similarity index 87% rename from pkg/models/source.go rename to pkg/models/graphModels/source.go index 00040ae..5e3795b 100644 --- a/pkg/models/source.go +++ b/pkg/models/graphModels/source.go @@ -1,4 +1,4 @@ -package models +package graphModels type AnthroveSource struct { DisplayName string `json:"display_name"` diff --git a/pkg/models/tag.go b/pkg/models/graphModels/tag.go similarity index 80% rename from pkg/models/tag.go rename to pkg/models/graphModels/tag.go index 8d0d1e6..699a1fc 100644 --- a/pkg/models/tag.go +++ b/pkg/models/graphModels/tag.go @@ -1,4 +1,4 @@ -package models +package graphModels type AnthroveTag struct { Name string `json:"name"` diff --git a/pkg/models/graphModels/user.go b/pkg/models/graphModels/user.go new file mode 100644 index 0000000..3b74a51 --- /dev/null +++ b/pkg/models/graphModels/user.go @@ -0,0 +1,8 @@ +package graphModels + +import "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + +type AnthroveUser struct { + UserID models.AnthroveUserID `json:"user_id"` + Relationship []AnthroveUserRelationship `json:"relationship"` +} diff --git a/pkg/models/pgModels/orm.go b/pkg/models/pgModels/orm.go new file mode 100644 index 0000000..bea5f1b --- /dev/null +++ b/pkg/models/pgModels/orm.go @@ -0,0 +1,13 @@ +package pgModels + +import ( + "gorm.io/gorm" + "time" +) + +type BaseModel struct { + ID string `gorm:"primaryKey"` + CreatedAt time.Time + UpdatedAt time.Time + DeletedAt gorm.DeletedAt `gorm:"index"` +} diff --git a/pkg/models/pgModels/post.go b/pkg/models/pgModels/post.go new file mode 100644 index 0000000..a4cf61a --- /dev/null +++ b/pkg/models/pgModels/post.go @@ -0,0 +1,14 @@ +package pgModels + +import ( + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" +) + +// Post model +type Post struct { + BaseModel + Rating models.Rating `gorm:"type:rating"` + Body string `gorm:"type:text"` + UserID int `gorm:"index"` + Status string `gorm:"type:post_status"` +} diff --git a/pkg/models/pgModels/source.go b/pkg/models/pgModels/source.go new file mode 100644 index 0000000..73e2535 --- /dev/null +++ b/pkg/models/pgModels/source.go @@ -0,0 +1,8 @@ +package pgModels + +// Source model +type Source struct { + BaseModel + DisplayName string `gorm:"type:text"` + Domain string `gorm:"type:text;not null;unique"` +} diff --git a/pkg/models/pgModels/tag.go b/pkg/models/pgModels/tag.go new file mode 100644 index 0000000..4c246a1 --- /dev/null +++ b/pkg/models/pgModels/tag.go @@ -0,0 +1,21 @@ +package pgModels + +import "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + +// Tag models +type Tag struct { + Name string `gorm:"primaryKey"` + Type models.TagType `gorm:"type:tag_type"` +} + +// TagAlias model +type TagAlias struct { + Name string `gorm:"primaryKey"` + TagID string `gorm:"index"` +} + +// TagGroup model +type TagGroup struct { + Name string `gorm:"primaryKey"` + TagID string `gorm:"index"` +} diff --git a/pkg/models/pgModels/user.go b/pkg/models/pgModels/user.go new file mode 100644 index 0000000..be072d8 --- /dev/null +++ b/pkg/models/pgModels/user.go @@ -0,0 +1,6 @@ +package pgModels + +// User model +type User struct { + BaseModel +} diff --git a/pkg/models/post.go b/pkg/models/post.go deleted file mode 100644 index e2d4b9b..0000000 --- a/pkg/models/post.go +++ /dev/null @@ -1,6 +0,0 @@ -package models - -type AnthrovePost struct { - PostID AnthrovePostID `json:"post_id"` - Rating AnthroveRating `json:"rating"` -} diff --git a/pkg/models/user.go b/pkg/models/user.go deleted file mode 100644 index af6e36c..0000000 --- a/pkg/models/user.go +++ /dev/null @@ -1,6 +0,0 @@ -package models - -type AnthroveUser struct { - UserID AnthroveUserID `json:"user_id"` - Relationship []AnthroveUserRelationship `json:"relationship"` -} -- 2.45.1 From 5a693063bbccbb90ca7699cf147e7daa029de338 Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 4 Jun 2024 08:49:46 +0200 Subject: [PATCH 008/124] feat(sources): finalized model with gorm annotation Signed-off-by: SoXX --- pkg/models/pgModels/post.go | 11 +++++++---- pkg/models/pgModels/postReference.go | 8 ++++++++ pkg/models/pgModels/source.go | 6 ++++-- pkg/models/pgModels/tag.go | 11 +++++++---- pkg/models/pgModels/user.go | 2 ++ pkg/models/pgModels/userFavorite.go | 9 +++++++++ pkg/models/pgModels/userSource.go | 8 ++++++++ 7 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 pkg/models/pgModels/postReference.go create mode 100644 pkg/models/pgModels/userFavorite.go create mode 100644 pkg/models/pgModels/userSource.go diff --git a/pkg/models/pgModels/post.go b/pkg/models/pgModels/post.go index a4cf61a..1ba9262 100644 --- a/pkg/models/pgModels/post.go +++ b/pkg/models/pgModels/post.go @@ -7,8 +7,11 @@ import ( // Post model type Post struct { BaseModel - Rating models.Rating `gorm:"type:rating"` - Body string `gorm:"type:text"` - UserID int `gorm:"index"` - Status string `gorm:"type:post_status"` + Rating models.Rating `gorm:"type:enum('safe','questionable','explicit')"` + Body string `gorm:"type:text"` + UserID int + Status string + Tags []Tag `gorm:"many2many:post_tags;"` + Favorites []UserFavorite `gorm:"foreignKey:PostID"` + References []PostReference `gorm:"foreignKey:PostID"` } diff --git a/pkg/models/pgModels/postReference.go b/pkg/models/pgModels/postReference.go new file mode 100644 index 0000000..ae4574c --- /dev/null +++ b/pkg/models/pgModels/postReference.go @@ -0,0 +1,8 @@ +package pgModels + +type PostReference struct { + PostID string `gorm:"primaryKey"` + SourceID string `gorm:"primaryKey"` + URL string `gorm:"not null;unique"` + SourcePostID string +} diff --git a/pkg/models/pgModels/source.go b/pkg/models/pgModels/source.go index 73e2535..22c727f 100644 --- a/pkg/models/pgModels/source.go +++ b/pkg/models/pgModels/source.go @@ -3,6 +3,8 @@ package pgModels // Source model type Source struct { BaseModel - DisplayName string `gorm:"type:text"` - Domain string `gorm:"type:text;not null;unique"` + DisplayName string + Domain string `gorm:"not null;unique"` + UserSources []UserSource `gorm:"foreignKey:SourceID"` + References []PostReference `gorm:"foreignKey:SourceID"` } diff --git a/pkg/models/pgModels/tag.go b/pkg/models/pgModels/tag.go index 4c246a1..406f744 100644 --- a/pkg/models/pgModels/tag.go +++ b/pkg/models/pgModels/tag.go @@ -4,18 +4,21 @@ import "git.dragse.it/anthrove/otter-space-sdk/pkg/models" // Tag models type Tag struct { - Name string `gorm:"primaryKey"` - Type models.TagType `gorm:"type:tag_type"` + Name string `gorm:"primaryKey"` + Type models.TagType + Aliases []TagAlias `gorm:"foreignKey:TagID"` + Groups []TagGroup `gorm:"foreignKey:TagID"` + Posts []Post `gorm:"many2many:post_tags;"` } // TagAlias model type TagAlias struct { Name string `gorm:"primaryKey"` - TagID string `gorm:"index"` + TagID string } // TagGroup model type TagGroup struct { Name string `gorm:"primaryKey"` - TagID string `gorm:"index"` + TagID string } diff --git a/pkg/models/pgModels/user.go b/pkg/models/pgModels/user.go index be072d8..7fe7e73 100644 --- a/pkg/models/pgModels/user.go +++ b/pkg/models/pgModels/user.go @@ -3,4 +3,6 @@ package pgModels // User model type User struct { BaseModel + Favorites []UserFavorite `gorm:"foreignKey:UserID"` + Sources []UserSource `gorm:"foreignKey:UserID"` } diff --git a/pkg/models/pgModels/userFavorite.go b/pkg/models/pgModels/userFavorite.go new file mode 100644 index 0000000..2e194a3 --- /dev/null +++ b/pkg/models/pgModels/userFavorite.go @@ -0,0 +1,9 @@ +package pgModels + +import "time" + +type UserFavorite struct { + UserID string `gorm:"primaryKey"` + PostID string `gorm:"primaryKey"` + CreatedAt time.Time +} diff --git a/pkg/models/pgModels/userSource.go b/pkg/models/pgModels/userSource.go new file mode 100644 index 0000000..7319994 --- /dev/null +++ b/pkg/models/pgModels/userSource.go @@ -0,0 +1,8 @@ +package pgModels + +type UserSource struct { + UserID string `gorm:"primaryKey"` + SourceID string `gorm:"primaryKey"` + AccountUsername string + AccountID string +} -- 2.45.1 From b2b354c60ff6867a969b697c170e9a4689f4070f Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 4 Jun 2024 09:33:35 +0200 Subject: [PATCH 009/124] feat(db): initial setup for migrations Signed-off-by: SoXX --- go.mod | 13 ++++++++---- go.sum | 40 +++++++++++++++++++++++++++++-------- pkg/database/postgres.go | 31 ++++++++++++++++++++++++++++ pkg/models/pgModels/post.go | 5 +---- 4 files changed, 73 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index dc9cdf6..a2ceed4 100644 --- a/go.mod +++ b/go.mod @@ -3,19 +3,24 @@ module git.dragse.it/anthrove/otter-space-sdk go 1.22.0 require ( + github.com/lib/pq v1.10.7 github.com/neo4j/neo4j-go-driver/v5 v5.17.0 + github.com/rubenv/sql-migrate v1.6.1 github.com/sirupsen/logrus v1.9.3 gorm.io/driver/postgres v1.5.7 gorm.io/gorm v1.25.10 ) require ( + github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect - github.com/jackc/pgx/v5 v5.4.3 // indirect + github.com/jackc/pgx/v5 v5.5.5 // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/text v0.14.0 // indirect ) diff --git a/go.sum b/go.sum index 2c77d3a..7d29fd6 100644 --- a/go.sum +++ b/go.sum @@ -1,20 +1,40 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs= +github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY= -github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= +github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= +github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= +github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/neo4j/neo4j-go-driver/v5 v5.17.0 h1:Bdqg1Y8Hd3uLYToXtBjysDYXTdMiP7zeUNUEwfbJkSo= github.com/neo4j/neo4j-go-driver/v5 v5.17.0/go.mod h1:Vff8OwT7QpLm7L2yYr85XNWe9Rbqlbeb9asNXJTHO4k= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= +github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rubenv/sql-migrate v1.6.1 h1:bo6/sjsan9HaXAsNxYP/jCEDUGibHp8JmOBw7NTGRos= +github.com/rubenv/sql-migrate v1.6.1/go.mod h1:tPzespupJS0jacLfhbwto/UjSX+8h2FdWB7ar+QlHa0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -22,14 +42,18 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index afb0fac..f151503 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -2,10 +2,14 @@ package database import ( "context" + "database/sql" "fmt" + "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" + _ "github.com/lib/pq" + migrate "github.com/rubenv/sql-migrate" gormPostgres "gorm.io/driver/postgres" "gorm.io/gorm" ) @@ -28,6 +32,13 @@ func (p postgresqlConnection) Connect(ctx context.Context, endpoint string, user if err != nil { return err } + + err = p.migrateDatabase(dsn) + + if err != nil { + return err + } + return nil } @@ -129,3 +140,23 @@ func (p postgresqlConnection) GetSourceByURL(ctx context.Context, sourceUrl stri //TODO implement me panic("implement me") } + +func (p postgresqlConnection) migrateDatabase(connectionString string) error { + dialect := "postgres" + migrations := &migrate.FileMigrationSource{ + Dir: "db/migrations", + } + + db, err := sql.Open(dialect, connectionString) + if err != nil { + return err + } + + n, err := migrate.Exec(db, dialect, migrations, migrate.Up) + if err != nil { + return err + } + fmt.Printf("Applied %d migrations!\n", n) + + return nil +} diff --git a/pkg/models/pgModels/post.go b/pkg/models/pgModels/post.go index 1ba9262..d2dd980 100644 --- a/pkg/models/pgModels/post.go +++ b/pkg/models/pgModels/post.go @@ -7,10 +7,7 @@ import ( // Post model type Post struct { BaseModel - Rating models.Rating `gorm:"type:enum('safe','questionable','explicit')"` - Body string `gorm:"type:text"` - UserID int - Status string + Rating models.Rating `gorm:"type:enum('safe','questionable','explicit')"` Tags []Tag `gorm:"many2many:post_tags;"` Favorites []UserFavorite `gorm:"foreignKey:PostID"` References []PostReference `gorm:"foreignKey:PostID"` -- 2.45.1 From 751f387b86a1e0b13ce79607a0f5aee47c4116fb Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 4 Jun 2024 13:06:38 +0200 Subject: [PATCH 010/124] feat(db): finalizing migration statements Signed-off-by: SoXX --- db/migrations/001_create_enum_Rating_2024_06_04.sql | 9 +++++++++ .../002_create_enum_TagType_2024_06_04.sql | 13 +++++++++++++ db/migrations/003_create_table_Post_2024_06_04.sql | 10 ++++++++++ .../004_create_table_Source_2024_06_04.sql | 11 +++++++++++ db/migrations/005_create_table_Tag_2024_06_04.sql | 9 +++++++++ db/migrations/006_create_table_User_2024_06_04.sql | 9 +++++++++ .../007_create_table_PostReference_2024_06_04.sql | 12 ++++++++++++ .../008_create_table_TagAlias_2024_06_04.sql | 8 ++++++++ .../009_create_table_TagGroup_2024_06_04.sql | 9 +++++++++ .../010_create_table_UserFavorite_2024_06_04.sql | 11 +++++++++++ .../011_create_table_UserSource_2024_06_04.sql | 13 +++++++++++++ pkg/database/postgres.go | 9 ++++----- 12 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 db/migrations/001_create_enum_Rating_2024_06_04.sql create mode 100644 db/migrations/002_create_enum_TagType_2024_06_04.sql create mode 100644 db/migrations/003_create_table_Post_2024_06_04.sql create mode 100644 db/migrations/004_create_table_Source_2024_06_04.sql create mode 100644 db/migrations/005_create_table_Tag_2024_06_04.sql create mode 100644 db/migrations/006_create_table_User_2024_06_04.sql create mode 100644 db/migrations/007_create_table_PostReference_2024_06_04.sql create mode 100644 db/migrations/008_create_table_TagAlias_2024_06_04.sql create mode 100644 db/migrations/009_create_table_TagGroup_2024_06_04.sql create mode 100644 db/migrations/010_create_table_UserFavorite_2024_06_04.sql create mode 100644 db/migrations/011_create_table_UserSource_2024_06_04.sql diff --git a/db/migrations/001_create_enum_Rating_2024_06_04.sql b/db/migrations/001_create_enum_Rating_2024_06_04.sql new file mode 100644 index 0000000..0af65ae --- /dev/null +++ b/db/migrations/001_create_enum_Rating_2024_06_04.sql @@ -0,0 +1,9 @@ +-- +migrate Up +CREATE TYPE Rating AS ENUM ( + 'safe', + 'questionable', + 'explicit' + ); + +-- +migrate Down +DROP TYPE Rating; diff --git a/db/migrations/002_create_enum_TagType_2024_06_04.sql b/db/migrations/002_create_enum_TagType_2024_06_04.sql new file mode 100644 index 0000000..0a95264 --- /dev/null +++ b/db/migrations/002_create_enum_TagType_2024_06_04.sql @@ -0,0 +1,13 @@ +-- +migrate Up +CREATE TYPE TagType AS ENUM ( + 'general', + 'species', + 'character', + 'artist', + 'lore', + 'meta', + 'invalid' + ); + +-- +migrate Down +DROP TYPE TagType; diff --git a/db/migrations/003_create_table_Post_2024_06_04.sql b/db/migrations/003_create_table_Post_2024_06_04.sql new file mode 100644 index 0000000..11957e1 --- /dev/null +++ b/db/migrations/003_create_table_Post_2024_06_04.sql @@ -0,0 +1,10 @@ +-- +migrate Up +CREATE TABLE "Post" +( + id VARCHAR(25) PRIMARY KEY, + rating Rating, + created_at TIMESTAMP +); + +-- +migrate Down +DROP TYPE Post; diff --git a/db/migrations/004_create_table_Source_2024_06_04.sql b/db/migrations/004_create_table_Source_2024_06_04.sql new file mode 100644 index 0000000..c52015f --- /dev/null +++ b/db/migrations/004_create_table_Source_2024_06_04.sql @@ -0,0 +1,11 @@ +-- +migrate Up +CREATE TABLE "Source" +( + id VARCHAR(25) PRIMARY KEY, + display_name TEXT, + domain TEXT NOT NULL UNIQUE +); + + +-- +migrate Down +DROP TABLE "Source"; \ No newline at end of file diff --git a/db/migrations/005_create_table_Tag_2024_06_04.sql b/db/migrations/005_create_table_Tag_2024_06_04.sql new file mode 100644 index 0000000..9b25afe --- /dev/null +++ b/db/migrations/005_create_table_Tag_2024_06_04.sql @@ -0,0 +1,9 @@ +-- +migrate Up +CREATE TABLE "Tag" +( + name TEXT PRIMARY KEY, + type TagType +); + +-- +migrate Down +DROP TABLE "Tag"; \ No newline at end of file diff --git a/db/migrations/006_create_table_User_2024_06_04.sql b/db/migrations/006_create_table_User_2024_06_04.sql new file mode 100644 index 0000000..56216f8 --- /dev/null +++ b/db/migrations/006_create_table_User_2024_06_04.sql @@ -0,0 +1,9 @@ +-- +migrate Up +CREATE TABLE "User" +( + id TEXT PRIMARY KEY, + created_at TIMESTAMP +); + +-- +migrate Down +DROP TABLE "User"; \ No newline at end of file diff --git a/db/migrations/007_create_table_PostReference_2024_06_04.sql b/db/migrations/007_create_table_PostReference_2024_06_04.sql new file mode 100644 index 0000000..f0001e7 --- /dev/null +++ b/db/migrations/007_create_table_PostReference_2024_06_04.sql @@ -0,0 +1,12 @@ +-- +migrate Up +CREATE TABLE "PostReference" +( + post_id TEXT REFERENCES "Post" (id), + source_id TEXT REFERENCES "Source" (id), + url TEXT NOT NULL UNIQUE, + source_post_id TEXT, + PRIMARY KEY (post_id, source_id) +); + +-- +migrate Down +DROP TABLE "PostReference"; \ No newline at end of file diff --git a/db/migrations/008_create_table_TagAlias_2024_06_04.sql b/db/migrations/008_create_table_TagAlias_2024_06_04.sql new file mode 100644 index 0000000..6e69fad --- /dev/null +++ b/db/migrations/008_create_table_TagAlias_2024_06_04.sql @@ -0,0 +1,8 @@ +-- +migrate Up +CREATE TABLE "TagAlias" +( + name TEXT PRIMARY KEY, + tag_id TEXT REFERENCES "Tag" (name) +); +-- +migrate Down +DROP TABLE "TagAlias"; \ No newline at end of file diff --git a/db/migrations/009_create_table_TagGroup_2024_06_04.sql b/db/migrations/009_create_table_TagGroup_2024_06_04.sql new file mode 100644 index 0000000..da305cd --- /dev/null +++ b/db/migrations/009_create_table_TagGroup_2024_06_04.sql @@ -0,0 +1,9 @@ +-- +migrate Up +CREATE TABLE "TagGroup" +( + name TEXT PRIMARY KEY, + tag_id TEXT REFERENCES "Tag" (name) +); + +-- +migrate Down +DROP TABLE "TagGroup"; \ No newline at end of file diff --git a/db/migrations/010_create_table_UserFavorite_2024_06_04.sql b/db/migrations/010_create_table_UserFavorite_2024_06_04.sql new file mode 100644 index 0000000..2058ab1 --- /dev/null +++ b/db/migrations/010_create_table_UserFavorite_2024_06_04.sql @@ -0,0 +1,11 @@ +-- +migrate Up +CREATE TABLE "UserFavorites" +( + user_id TEXT REFERENCES "User" (id), + post_id TEXT REFERENCES "Post" (id), + created_at TIMESTAMP, + PRIMARY KEY (user_id, post_id) +); + +-- +migrate Down +DROP TABLE "UserFavorites"; \ No newline at end of file diff --git a/db/migrations/011_create_table_UserSource_2024_06_04.sql b/db/migrations/011_create_table_UserSource_2024_06_04.sql new file mode 100644 index 0000000..8ba7201 --- /dev/null +++ b/db/migrations/011_create_table_UserSource_2024_06_04.sql @@ -0,0 +1,13 @@ +-- +migrate Up +CREATE TABLE "UserSource" +( + user_id TEXT REFERENCES "User" (id), + source_id TEXT REFERENCES "Source" (id), + account_username TEXT, + account_id TEXT, + PRIMARY KEY (user_id, source_id) +); + + +-- +migrate Down +DROP TABLE "UserSource"; \ No newline at end of file diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index f151503..77870f4 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -25,16 +25,15 @@ func NewPostgresqlConnection() OtterSpace { } func (p postgresqlConnection) Connect(ctx context.Context, endpoint string, username string, password string, database string, port int, ssl string, timezone string) error { - dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s TimeZone=%s", endpoint, username, password, database, port, ssl, timezone) - db, err := gorm.Open(gormPostgres.Open(dsn), &gorm.Config{}) - p.db = db + var err error + + err = p.migrateDatabase(dsn) if err != nil { return err } - err = p.migrateDatabase(dsn) - + p.db, err = gorm.Open(gormPostgres.Open(dsn), &gorm.Config{}) if err != nil { return err } -- 2.45.1 From 549c1ca5731f2d558642f25721b7985d6d69f90d Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 4 Jun 2024 13:07:18 +0200 Subject: [PATCH 011/124] docs(db): removing unused entities Signed-off-by: SoXX --- pkg/models/README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkg/models/README.md b/pkg/models/README.md index 7c824d0..af61315 100644 --- a/pkg/models/README.md +++ b/pkg/models/README.md @@ -11,9 +11,6 @@ Table User { Table Post { id varchar(25) [primary key] rating Rating - body text [note: 'Content of the post'] - user_id integer - status post_status created_at timestamp } -- 2.45.1 From b65e942f24a2e7660087d0b712ffe164eb871740 Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 4 Jun 2024 13:28:14 +0200 Subject: [PATCH 012/124] feat(db): embed migration files Signed-off-by: SoXX --- .../001_create_enum_Rating_2024_06_04.sql | 0 .../002_create_enum_TagType_2024_06_04.sql | 0 .../003_create_table_Post_2024_06_04.sql | 0 .../004_create_table_Source_2024_06_04.sql | 0 .../005_create_table_Tag_2024_06_04.sql | 0 .../006_create_table_User_2024_06_04.sql | 0 ..._create_table_PostReference_2024_06_04.sql | 0 .../008_create_table_TagAlias_2024_06_04.sql | 0 .../009_create_table_TagGroup_2024_06_04.sql | 0 ...0_create_table_UserFavorite_2024_06_04.sql | 0 ...011_create_table_UserSource_2024_06_04.sql | 0 pkg/database/postgres.go | 21 +++++++++++++------ 12 files changed, 15 insertions(+), 6 deletions(-) rename {db => pkg/database}/migrations/001_create_enum_Rating_2024_06_04.sql (100%) rename {db => pkg/database}/migrations/002_create_enum_TagType_2024_06_04.sql (100%) rename {db => pkg/database}/migrations/003_create_table_Post_2024_06_04.sql (100%) rename {db => pkg/database}/migrations/004_create_table_Source_2024_06_04.sql (100%) rename {db => pkg/database}/migrations/005_create_table_Tag_2024_06_04.sql (100%) rename {db => pkg/database}/migrations/006_create_table_User_2024_06_04.sql (100%) rename {db => pkg/database}/migrations/007_create_table_PostReference_2024_06_04.sql (100%) rename {db => pkg/database}/migrations/008_create_table_TagAlias_2024_06_04.sql (100%) rename {db => pkg/database}/migrations/009_create_table_TagGroup_2024_06_04.sql (100%) rename {db => pkg/database}/migrations/010_create_table_UserFavorite_2024_06_04.sql (100%) rename {db => pkg/database}/migrations/011_create_table_UserSource_2024_06_04.sql (100%) diff --git a/db/migrations/001_create_enum_Rating_2024_06_04.sql b/pkg/database/migrations/001_create_enum_Rating_2024_06_04.sql similarity index 100% rename from db/migrations/001_create_enum_Rating_2024_06_04.sql rename to pkg/database/migrations/001_create_enum_Rating_2024_06_04.sql diff --git a/db/migrations/002_create_enum_TagType_2024_06_04.sql b/pkg/database/migrations/002_create_enum_TagType_2024_06_04.sql similarity index 100% rename from db/migrations/002_create_enum_TagType_2024_06_04.sql rename to pkg/database/migrations/002_create_enum_TagType_2024_06_04.sql diff --git a/db/migrations/003_create_table_Post_2024_06_04.sql b/pkg/database/migrations/003_create_table_Post_2024_06_04.sql similarity index 100% rename from db/migrations/003_create_table_Post_2024_06_04.sql rename to pkg/database/migrations/003_create_table_Post_2024_06_04.sql diff --git a/db/migrations/004_create_table_Source_2024_06_04.sql b/pkg/database/migrations/004_create_table_Source_2024_06_04.sql similarity index 100% rename from db/migrations/004_create_table_Source_2024_06_04.sql rename to pkg/database/migrations/004_create_table_Source_2024_06_04.sql diff --git a/db/migrations/005_create_table_Tag_2024_06_04.sql b/pkg/database/migrations/005_create_table_Tag_2024_06_04.sql similarity index 100% rename from db/migrations/005_create_table_Tag_2024_06_04.sql rename to pkg/database/migrations/005_create_table_Tag_2024_06_04.sql diff --git a/db/migrations/006_create_table_User_2024_06_04.sql b/pkg/database/migrations/006_create_table_User_2024_06_04.sql similarity index 100% rename from db/migrations/006_create_table_User_2024_06_04.sql rename to pkg/database/migrations/006_create_table_User_2024_06_04.sql diff --git a/db/migrations/007_create_table_PostReference_2024_06_04.sql b/pkg/database/migrations/007_create_table_PostReference_2024_06_04.sql similarity index 100% rename from db/migrations/007_create_table_PostReference_2024_06_04.sql rename to pkg/database/migrations/007_create_table_PostReference_2024_06_04.sql diff --git a/db/migrations/008_create_table_TagAlias_2024_06_04.sql b/pkg/database/migrations/008_create_table_TagAlias_2024_06_04.sql similarity index 100% rename from db/migrations/008_create_table_TagAlias_2024_06_04.sql rename to pkg/database/migrations/008_create_table_TagAlias_2024_06_04.sql diff --git a/db/migrations/009_create_table_TagGroup_2024_06_04.sql b/pkg/database/migrations/009_create_table_TagGroup_2024_06_04.sql similarity index 100% rename from db/migrations/009_create_table_TagGroup_2024_06_04.sql rename to pkg/database/migrations/009_create_table_TagGroup_2024_06_04.sql diff --git a/db/migrations/010_create_table_UserFavorite_2024_06_04.sql b/pkg/database/migrations/010_create_table_UserFavorite_2024_06_04.sql similarity index 100% rename from db/migrations/010_create_table_UserFavorite_2024_06_04.sql rename to pkg/database/migrations/010_create_table_UserFavorite_2024_06_04.sql diff --git a/db/migrations/011_create_table_UserSource_2024_06_04.sql b/pkg/database/migrations/011_create_table_UserSource_2024_06_04.sql similarity index 100% rename from db/migrations/011_create_table_UserSource_2024_06_04.sql rename to pkg/database/migrations/011_create_table_UserSource_2024_06_04.sql diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 77870f4..f8773e6 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -3,6 +3,7 @@ package database import ( "context" "database/sql" + "embed" "fmt" "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" @@ -10,10 +11,14 @@ import ( "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" _ "github.com/lib/pq" migrate "github.com/rubenv/sql-migrate" + log "github.com/sirupsen/logrus" gormPostgres "gorm.io/driver/postgres" "gorm.io/gorm" ) +//go:embed migrations/*.sql +var embedMigrations embed.FS + type postgresqlConnection struct { db *gorm.DB } @@ -142,20 +147,24 @@ func (p postgresqlConnection) GetSourceByURL(ctx context.Context, sourceUrl stri func (p postgresqlConnection) migrateDatabase(connectionString string) error { dialect := "postgres" - migrations := &migrate.FileMigrationSource{ - Dir: "db/migrations", - } + migrations := &migrate.EmbedFileSystemMigrationSource{FileSystem: embedMigrations, Root: "migrations"} db, err := sql.Open(dialect, connectionString) if err != nil { - return err + return fmt.Errorf("postgres migration: %v", err) } n, err := migrate.Exec(db, dialect, migrations, migrate.Up) if err != nil { - return err + return fmt.Errorf("postgres migration: %v", err) + } + if n != 0 { + log.Infof("postgres migration: applied %d migrations!", n) + + } else { + log.Info("postgres migration: nothing to migrate") + } - fmt.Printf("Applied %d migrations!\n", n) return nil } -- 2.45.1 From ebd25580febfed169ea398158c31f62975b9b981 Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 4 Jun 2024 13:35:14 +0200 Subject: [PATCH 013/124] feat(db): reduce to one migration file Signed-off-by: SoXX --- .../001_create_enum_Rating_2024_06_04.sql | 9 -- .../migrations/001_inital_database.sql | 93 +++++++++++++++++++ .../002_create_enum_TagType_2024_06_04.sql | 13 --- .../003_create_table_Post_2024_06_04.sql | 10 -- .../004_create_table_Source_2024_06_04.sql | 11 --- .../005_create_table_Tag_2024_06_04.sql | 9 -- .../006_create_table_User_2024_06_04.sql | 9 -- ..._create_table_PostReference_2024_06_04.sql | 12 --- .../008_create_table_TagAlias_2024_06_04.sql | 8 -- .../009_create_table_TagGroup_2024_06_04.sql | 9 -- ...0_create_table_UserFavorite_2024_06_04.sql | 11 --- ...011_create_table_UserSource_2024_06_04.sql | 13 --- 12 files changed, 93 insertions(+), 114 deletions(-) delete mode 100644 pkg/database/migrations/001_create_enum_Rating_2024_06_04.sql create mode 100644 pkg/database/migrations/001_inital_database.sql delete mode 100644 pkg/database/migrations/002_create_enum_TagType_2024_06_04.sql delete mode 100644 pkg/database/migrations/003_create_table_Post_2024_06_04.sql delete mode 100644 pkg/database/migrations/004_create_table_Source_2024_06_04.sql delete mode 100644 pkg/database/migrations/005_create_table_Tag_2024_06_04.sql delete mode 100644 pkg/database/migrations/006_create_table_User_2024_06_04.sql delete mode 100644 pkg/database/migrations/007_create_table_PostReference_2024_06_04.sql delete mode 100644 pkg/database/migrations/008_create_table_TagAlias_2024_06_04.sql delete mode 100644 pkg/database/migrations/009_create_table_TagGroup_2024_06_04.sql delete mode 100644 pkg/database/migrations/010_create_table_UserFavorite_2024_06_04.sql delete mode 100644 pkg/database/migrations/011_create_table_UserSource_2024_06_04.sql diff --git a/pkg/database/migrations/001_create_enum_Rating_2024_06_04.sql b/pkg/database/migrations/001_create_enum_Rating_2024_06_04.sql deleted file mode 100644 index 0af65ae..0000000 --- a/pkg/database/migrations/001_create_enum_Rating_2024_06_04.sql +++ /dev/null @@ -1,9 +0,0 @@ --- +migrate Up -CREATE TYPE Rating AS ENUM ( - 'safe', - 'questionable', - 'explicit' - ); - --- +migrate Down -DROP TYPE Rating; diff --git a/pkg/database/migrations/001_inital_database.sql b/pkg/database/migrations/001_inital_database.sql new file mode 100644 index 0000000..896c850 --- /dev/null +++ b/pkg/database/migrations/001_inital_database.sql @@ -0,0 +1,93 @@ +-- +migrate Up +CREATE TYPE Rating AS ENUM ( + 'safe', + 'questionable', + 'explicit' + ); + +CREATE TYPE TagType AS ENUM ( + 'general', + 'species', + 'character', + 'artist', + 'lore', + 'meta', + 'invalid' + ); + +CREATE TABLE "Post" +( + id VARCHAR(25) PRIMARY KEY, + rating Rating, + created_at TIMESTAMP +); + +CREATE TABLE "Source" +( + id VARCHAR(25) PRIMARY KEY, + display_name TEXT, + domain TEXT NOT NULL UNIQUE +); + +CREATE TABLE "Tag" +( + name TEXT PRIMARY KEY, + type TagType +); + +CREATE TABLE "User" +( + id TEXT PRIMARY KEY, + created_at TIMESTAMP +); + +CREATE TABLE "PostReference" +( + post_id TEXT REFERENCES "Post" (id), + source_id TEXT REFERENCES "Source" (id), + url TEXT NOT NULL UNIQUE, + source_post_id TEXT, + PRIMARY KEY (post_id, source_id) +); + +CREATE TABLE "TagAlias" +( + name TEXT PRIMARY KEY, + tag_id TEXT REFERENCES "Tag" (name) +); + +CREATE TABLE "TagGroup" +( + name TEXT PRIMARY KEY, + tag_id TEXT REFERENCES "Tag" (name) +); + +CREATE TABLE "UserFavorites" +( + user_id TEXT REFERENCES "User" (id), + post_id TEXT REFERENCES "Post" (id), + created_at TIMESTAMP, + PRIMARY KEY (user_id, post_id) +); + +CREATE TABLE "UserSource" +( + user_id TEXT REFERENCES "User" (id), + source_id TEXT REFERENCES "Source" (id), + account_username TEXT, + account_id TEXT, + PRIMARY KEY (user_id, source_id) +); + +-- +migrate Down +DROP TYPE Rating; +DROP TYPE TagType; +DROP TYPE Post; +DROP TYPE Source; +DROP TYPE Tag; +DROP TYPE User; +DROP TYPE PostReference; +DROP TYPE TagAlias; +DROP TYPE TagGroup; +DROP TYPE UserFavorites; +DROP TYPE UserSource; \ No newline at end of file diff --git a/pkg/database/migrations/002_create_enum_TagType_2024_06_04.sql b/pkg/database/migrations/002_create_enum_TagType_2024_06_04.sql deleted file mode 100644 index 0a95264..0000000 --- a/pkg/database/migrations/002_create_enum_TagType_2024_06_04.sql +++ /dev/null @@ -1,13 +0,0 @@ --- +migrate Up -CREATE TYPE TagType AS ENUM ( - 'general', - 'species', - 'character', - 'artist', - 'lore', - 'meta', - 'invalid' - ); - --- +migrate Down -DROP TYPE TagType; diff --git a/pkg/database/migrations/003_create_table_Post_2024_06_04.sql b/pkg/database/migrations/003_create_table_Post_2024_06_04.sql deleted file mode 100644 index 11957e1..0000000 --- a/pkg/database/migrations/003_create_table_Post_2024_06_04.sql +++ /dev/null @@ -1,10 +0,0 @@ --- +migrate Up -CREATE TABLE "Post" -( - id VARCHAR(25) PRIMARY KEY, - rating Rating, - created_at TIMESTAMP -); - --- +migrate Down -DROP TYPE Post; diff --git a/pkg/database/migrations/004_create_table_Source_2024_06_04.sql b/pkg/database/migrations/004_create_table_Source_2024_06_04.sql deleted file mode 100644 index c52015f..0000000 --- a/pkg/database/migrations/004_create_table_Source_2024_06_04.sql +++ /dev/null @@ -1,11 +0,0 @@ --- +migrate Up -CREATE TABLE "Source" -( - id VARCHAR(25) PRIMARY KEY, - display_name TEXT, - domain TEXT NOT NULL UNIQUE -); - - --- +migrate Down -DROP TABLE "Source"; \ No newline at end of file diff --git a/pkg/database/migrations/005_create_table_Tag_2024_06_04.sql b/pkg/database/migrations/005_create_table_Tag_2024_06_04.sql deleted file mode 100644 index 9b25afe..0000000 --- a/pkg/database/migrations/005_create_table_Tag_2024_06_04.sql +++ /dev/null @@ -1,9 +0,0 @@ --- +migrate Up -CREATE TABLE "Tag" -( - name TEXT PRIMARY KEY, - type TagType -); - --- +migrate Down -DROP TABLE "Tag"; \ No newline at end of file diff --git a/pkg/database/migrations/006_create_table_User_2024_06_04.sql b/pkg/database/migrations/006_create_table_User_2024_06_04.sql deleted file mode 100644 index 56216f8..0000000 --- a/pkg/database/migrations/006_create_table_User_2024_06_04.sql +++ /dev/null @@ -1,9 +0,0 @@ --- +migrate Up -CREATE TABLE "User" -( - id TEXT PRIMARY KEY, - created_at TIMESTAMP -); - --- +migrate Down -DROP TABLE "User"; \ No newline at end of file diff --git a/pkg/database/migrations/007_create_table_PostReference_2024_06_04.sql b/pkg/database/migrations/007_create_table_PostReference_2024_06_04.sql deleted file mode 100644 index f0001e7..0000000 --- a/pkg/database/migrations/007_create_table_PostReference_2024_06_04.sql +++ /dev/null @@ -1,12 +0,0 @@ --- +migrate Up -CREATE TABLE "PostReference" -( - post_id TEXT REFERENCES "Post" (id), - source_id TEXT REFERENCES "Source" (id), - url TEXT NOT NULL UNIQUE, - source_post_id TEXT, - PRIMARY KEY (post_id, source_id) -); - --- +migrate Down -DROP TABLE "PostReference"; \ No newline at end of file diff --git a/pkg/database/migrations/008_create_table_TagAlias_2024_06_04.sql b/pkg/database/migrations/008_create_table_TagAlias_2024_06_04.sql deleted file mode 100644 index 6e69fad..0000000 --- a/pkg/database/migrations/008_create_table_TagAlias_2024_06_04.sql +++ /dev/null @@ -1,8 +0,0 @@ --- +migrate Up -CREATE TABLE "TagAlias" -( - name TEXT PRIMARY KEY, - tag_id TEXT REFERENCES "Tag" (name) -); --- +migrate Down -DROP TABLE "TagAlias"; \ No newline at end of file diff --git a/pkg/database/migrations/009_create_table_TagGroup_2024_06_04.sql b/pkg/database/migrations/009_create_table_TagGroup_2024_06_04.sql deleted file mode 100644 index da305cd..0000000 --- a/pkg/database/migrations/009_create_table_TagGroup_2024_06_04.sql +++ /dev/null @@ -1,9 +0,0 @@ --- +migrate Up -CREATE TABLE "TagGroup" -( - name TEXT PRIMARY KEY, - tag_id TEXT REFERENCES "Tag" (name) -); - --- +migrate Down -DROP TABLE "TagGroup"; \ No newline at end of file diff --git a/pkg/database/migrations/010_create_table_UserFavorite_2024_06_04.sql b/pkg/database/migrations/010_create_table_UserFavorite_2024_06_04.sql deleted file mode 100644 index 2058ab1..0000000 --- a/pkg/database/migrations/010_create_table_UserFavorite_2024_06_04.sql +++ /dev/null @@ -1,11 +0,0 @@ --- +migrate Up -CREATE TABLE "UserFavorites" -( - user_id TEXT REFERENCES "User" (id), - post_id TEXT REFERENCES "Post" (id), - created_at TIMESTAMP, - PRIMARY KEY (user_id, post_id) -); - --- +migrate Down -DROP TABLE "UserFavorites"; \ No newline at end of file diff --git a/pkg/database/migrations/011_create_table_UserSource_2024_06_04.sql b/pkg/database/migrations/011_create_table_UserSource_2024_06_04.sql deleted file mode 100644 index 8ba7201..0000000 --- a/pkg/database/migrations/011_create_table_UserSource_2024_06_04.sql +++ /dev/null @@ -1,13 +0,0 @@ --- +migrate Up -CREATE TABLE "UserSource" -( - user_id TEXT REFERENCES "User" (id), - source_id TEXT REFERENCES "Source" (id), - account_username TEXT, - account_id TEXT, - PRIMARY KEY (user_id, source_id) -); - - --- +migrate Down -DROP TABLE "UserSource"; \ No newline at end of file -- 2.45.1 From f0bd89759cbf17bb9a383da023f6cad586dc4f7c Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 4 Jun 2024 13:44:15 +0200 Subject: [PATCH 014/124] refactor(db): logging & tracing Signed-off-by: SoXX --- pkg/database/postgres.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index f8773e6..cff9d4e 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -38,11 +38,15 @@ func (p postgresqlConnection) Connect(ctx context.Context, endpoint string, user return err } + log.Infof("OtterSpace: migration compleate") + p.db, err = gorm.Open(gormPostgres.Open(dsn), &gorm.Config{}) if err != nil { return err } + log.Infof("OtterSpace: postgres connection established") + return nil } @@ -159,10 +163,10 @@ func (p postgresqlConnection) migrateDatabase(connectionString string) error { return fmt.Errorf("postgres migration: %v", err) } if n != 0 { - log.Infof("postgres migration: applied %d migrations!", n) + log.Tracef("postgres migration: applied %d migrations!", n) } else { - log.Info("postgres migration: nothing to migrate") + log.Trace("postgres migration: nothing to migrate") } -- 2.45.1 From ccb7cff4fca3ea7b0c4ae74cf5dbc76f0b5d113a Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 4 Jun 2024 13:59:38 +0200 Subject: [PATCH 015/124] refactor(db): removed unused context Signed-off-by: SoXX --- pkg/database/postgres.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index cff9d4e..7680441 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -29,7 +29,7 @@ func NewPostgresqlConnection() OtterSpace { } } -func (p postgresqlConnection) Connect(ctx context.Context, endpoint string, username string, password string, database string, port int, ssl string, timezone string) error { +func (p postgresqlConnection) Connect(_ context.Context, endpoint string, username string, password string, database string, port int, ssl string, timezone string) error { dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s TimeZone=%s", endpoint, username, password, database, port, ssl, timezone) var err error -- 2.45.1 From 5aa1542074899e46a3e269a5460742f2359433b8 Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 4 Jun 2024 14:00:00 +0200 Subject: [PATCH 016/124] feat(db): corrected tables Signed-off-by: SoXX --- pkg/database/migrations/001_inital_database.sql | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/database/migrations/001_inital_database.sql b/pkg/database/migrations/001_inital_database.sql index 896c850..a3c1146 100644 --- a/pkg/database/migrations/001_inital_database.sql +++ b/pkg/database/migrations/001_inital_database.sql @@ -17,14 +17,14 @@ CREATE TYPE TagType AS ENUM ( CREATE TABLE "Post" ( - id VARCHAR(25) PRIMARY KEY, + id VARCHAR(25) UNIQUE PRIMARY KEY, rating Rating, - created_at TIMESTAMP + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE "Source" ( - id VARCHAR(25) PRIMARY KEY, + id VARCHAR(25) UNIQUE PRIMARY KEY, display_name TEXT, domain TEXT NOT NULL UNIQUE ); @@ -37,8 +37,8 @@ CREATE TABLE "Tag" CREATE TABLE "User" ( - id TEXT PRIMARY KEY, - created_at TIMESTAMP + id TEXT UNIQUE PRIMARY KEY, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE "PostReference" @@ -66,7 +66,7 @@ CREATE TABLE "UserFavorites" ( user_id TEXT REFERENCES "User" (id), post_id TEXT REFERENCES "Post" (id), - created_at TIMESTAMP, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (user_id, post_id) ); -- 2.45.1 From 8f87eb6ce8d325b7bbbd86ed75d9f3a9c93edd08 Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 4 Jun 2024 15:16:37 +0200 Subject: [PATCH 017/124] feat(db): start implementing sources & fixing issues that come along the way Signed-off-by: SoXX --- internal/postgres/source.go | 45 ++++++++++-- internal/utils/modelConvert.go | 27 ++++++++ .../migrations/001_inital_database.sql | 9 ++- pkg/database/postgres.go | 69 +++++++++++-------- pkg/models/pgModels/source.go | 5 ++ 5 files changed, 120 insertions(+), 35 deletions(-) create mode 100644 internal/utils/modelConvert.go diff --git a/internal/postgres/source.go b/internal/postgres/source.go index 956c53b..3d2cdca 100644 --- a/internal/postgres/source.go +++ b/internal/postgres/source.go @@ -2,14 +2,33 @@ package postgres import ( "context" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" + + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) -// GetAllSourceNodes returns a list of all models.AnthroveSource -func GetAllSourceNodes(ctx context.Context, db *gorm.DB) ([]graphModels.AnthroveSource, error) { - var sources []graphModels.AnthroveSource +// CreateSourceNode creates a pgModels.Source +func CreateSourceNode(ctx context.Context, db *gorm.DB, anthroveSource *pgModels.Source) error { + + result := db.WithContext(ctx).Create(anthroveSource) + + if result.Error != nil { + return result.Error + } + + log.WithFields(log.Fields{ + "node_source_url": anthroveSource.Domain, + "node_source_displayName": anthroveSource.DisplayName, + "node_source_icon": anthroveSource.Icon, + }).Trace("database: created source node") + + return nil +} + +// GetAllSourceNodes returns a list of all pgModels.Source +func GetAllSourceNodes(ctx context.Context, db *gorm.DB) ([]pgModels.Source, error) { + var sources []pgModels.Source result := db.WithContext(ctx).Find(&sources) @@ -23,3 +42,21 @@ func GetAllSourceNodes(ctx context.Context, db *gorm.DB) ([]graphModels.Anthrove return sources, nil } + +// GetSourceNodesByURL returns the first source it finds based on the domain +func GetSourceNodesByURL(ctx context.Context, db *gorm.DB, domain string) (*pgModels.Source, error) { + + var sources *pgModels.Source + + result := db.WithContext(ctx).Where("domain = ?", domain).First(&sources) + + if result.Error != nil { + return nil, result.Error + } + + log.WithFields(log.Fields{ + "tag_amount": result.RowsAffected, + }).Trace("database: get all source nodes") + + return sources, nil +} diff --git a/internal/utils/modelConvert.go b/internal/utils/modelConvert.go new file mode 100644 index 0000000..cc75258 --- /dev/null +++ b/internal/utils/modelConvert.go @@ -0,0 +1,27 @@ +package utils + +import ( + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" +) + +// GraphConvertSource converts a graphModels.AnthroveSource to a pgModels.Source +func GraphConvertSource(graphSource *graphModels.AnthroveSource) *pgModels.Source { + pgSource := &pgModels.Source{ + DisplayName: graphSource.DisplayName, + Domain: graphSource.Domain, + Icon: graphSource.Icon, + } + return pgSource +} + +// PostgresConvertToAnthroveSource converts a pgModels.Source to a graphModels.AnthroveSource +func PostgresConvertToAnthroveSource(pgSource *pgModels.Source) *graphModels.AnthroveSource { + graphSource := &graphModels.AnthroveSource{ + DisplayName: pgSource.DisplayName, + Domain: pgSource.Domain, + Icon: pgSource.Icon, + } + + return graphSource +} diff --git a/pkg/database/migrations/001_inital_database.sql b/pkg/database/migrations/001_inital_database.sql index a3c1146..00fcf9c 100644 --- a/pkg/database/migrations/001_inital_database.sql +++ b/pkg/database/migrations/001_inital_database.sql @@ -1,3 +1,9 @@ +-- TODO: Add the following fields where its defined in the model +-- created_at +-- updated_at +-- deleted_at + + -- +migrate Up CREATE TYPE Rating AS ENUM ( 'safe', @@ -24,8 +30,9 @@ CREATE TABLE "Post" CREATE TABLE "Source" ( - id VARCHAR(25) UNIQUE PRIMARY KEY, + id VARCHAR(25) UNIQUE PRIMARY KEY, display_name TEXT, + icon TEXT, domain TEXT NOT NULL UNIQUE ); diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 7680441..5ed0afe 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -7,6 +7,7 @@ import ( "fmt" "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" + "git.dragse.it/anthrove/otter-space-sdk/internal/utils" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" _ "github.com/lib/pq" @@ -29,7 +30,7 @@ func NewPostgresqlConnection() OtterSpace { } } -func (p postgresqlConnection) Connect(_ context.Context, endpoint string, username string, password string, database string, port int, ssl string, timezone string) error { +func (p *postgresqlConnection) Connect(_ context.Context, endpoint string, username string, password string, database string, port int, ssl string, timezone string) error { dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s TimeZone=%s", endpoint, username, password, database, port, ssl, timezone) var err error @@ -40,7 +41,8 @@ func (p postgresqlConnection) Connect(_ context.Context, endpoint string, userna log.Infof("OtterSpace: migration compleate") - p.db, err = gorm.Open(gormPostgres.Open(dsn), &gorm.Config{}) + db, err := gorm.Open(gormPostgres.Open(dsn), &gorm.Config{}) + p.db = db if err != nil { return err } @@ -50,106 +52,113 @@ func (p postgresqlConnection) Connect(_ context.Context, endpoint string, userna return nil } -func (p postgresqlConnection) AddUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error { +func (p *postgresqlConnection) AddUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error { //TODO implement me panic("implement me") } -func (p postgresqlConnection) AddSource(ctx context.Context, anthroveSource *graphModels.AnthroveSource) error { +func (p *postgresqlConnection) AddSource(ctx context.Context, anthroveSource *graphModels.AnthroveSource) error { + source := utils.GraphConvertSource(anthroveSource) + return postgres.CreateSourceNode(ctx, p.db, source) +} + +func (p *postgresqlConnection) AddPost(ctx context.Context, anthrovePost *graphModels.AnthrovePost) error { //TODO implement me panic("implement me") } -func (p postgresqlConnection) AddPost(ctx context.Context, anthrovePost *graphModels.AnthrovePost) error { +func (p *postgresqlConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *graphModels.AnthroveTag) error { //TODO implement me panic("implement me") } -func (p postgresqlConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *graphModels.AnthroveTag) error { +func (p *postgresqlConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error { //TODO implement me panic("implement me") } -func (p postgresqlConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error { +func (p *postgresqlConnection) LinkUserWithPost(ctx context.Context, anthroveUser *graphModels.AnthroveUser, anthrovePost *graphModels.AnthrovePost) error { //TODO implement me panic("implement me") } -func (p postgresqlConnection) LinkUserWithPost(ctx context.Context, anthroveUser *graphModels.AnthroveUser, anthrovePost *graphModels.AnthrovePost) error { +func (p *postgresqlConnection) CheckUserPostLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) CheckUserPostLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) { +func (p *postgresqlConnection) CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *graphModels.AnthrovePost) (*graphModels.AnthrovePost, bool, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *graphModels.AnthrovePost) (*graphModels.AnthrovePost, bool, error) { +func (p *postgresqlConnection) CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*graphModels.AnthrovePost, bool, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*graphModels.AnthrovePost, bool, error) { +func (p *postgresqlConnection) CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*graphModels.AnthrovePost, bool, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*graphModels.AnthrovePost, bool, error) { +func (p *postgresqlConnection) GetUserFavoriteCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) GetUserFavoriteCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) { +func (p *postgresqlConnection) GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]graphModels.AnthroveUserRelationship, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]graphModels.AnthroveUserRelationship, error) { +func (p *postgresqlConnection) GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]graphModels.AnthroveUserRelationship, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]graphModels.AnthroveUserRelationship, error) { +func (p *postgresqlConnection) GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*graphModels.AnthroveUser, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*graphModels.AnthroveUser, error) { +func (p *postgresqlConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) { +func (p *postgresqlConnection) GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*graphModels.FavoriteList, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*graphModels.FavoriteList, error) { +func (p *postgresqlConnection) GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]graphModels.TagsWithFrequency, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]graphModels.TagsWithFrequency, error) { +func (p *postgresqlConnection) GetAllTags(ctx context.Context) ([]graphModels.TagsWithFrequency, error) { //TODO implement me panic("implement me") } -func (p postgresqlConnection) GetAllTags(ctx context.Context) ([]graphModels.TagsWithFrequency, error) { - //TODO implement me - panic("implement me") +func (p *postgresqlConnection) GetAllSources(ctx context.Context) ([]graphModels.AnthroveSource, error) { + var anthroveSources []graphModels.AnthroveSource + source, err := postgres.GetAllSourceNodes(ctx, p.db) + + for _, v := range source { + anthroveSource := utils.PostgresConvertToAnthroveSource(&v) + anthroveSources = append(anthroveSources, *anthroveSource) + } + return nil, err } -func (p postgresqlConnection) GetAllSources(ctx context.Context) ([]graphModels.AnthroveSource, error) { - return postgres.GetAllSourceNodes(ctx, p.db) +func (p *postgresqlConnection) GetSourceByURL(ctx context.Context, sourceUrl string) (*graphModels.AnthroveSource, error) { + source, err := postgres.GetSourceNodesByURL(ctx, p.db, sourceUrl) + return utils.PostgresConvertToAnthroveSource(source), err } -func (p postgresqlConnection) GetSourceByURL(ctx context.Context, sourceUrl string) (*graphModels.AnthroveSource, error) { - //TODO implement me - panic("implement me") -} - -func (p postgresqlConnection) migrateDatabase(connectionString string) error { +func (p *postgresqlConnection) migrateDatabase(connectionString string) error { dialect := "postgres" migrations := &migrate.EmbedFileSystemMigrationSource{FileSystem: embedMigrations, Root: "migrations"} diff --git a/pkg/models/pgModels/source.go b/pkg/models/pgModels/source.go index 22c727f..7159ea5 100644 --- a/pkg/models/pgModels/source.go +++ b/pkg/models/pgModels/source.go @@ -5,6 +5,11 @@ type Source struct { BaseModel DisplayName string Domain string `gorm:"not null;unique"` + Icon string `gorm:"not null"` UserSources []UserSource `gorm:"foreignKey:SourceID"` References []PostReference `gorm:"foreignKey:SourceID"` } + +func (Source) TableName() string { + return "Source" +} -- 2.45.1 From b248cbf0c798043c09cd7d7923ac535815d4561d Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 4 Jun 2024 23:14:02 +0200 Subject: [PATCH 018/124] feat(db): start implementing sources & fixing issues that come along the way Signed-off-by: SoXX --- go.mod | 1 + go.sum | 2 + internal/postgres/tag.go | 38 ++++++++++ internal/utils/modelConvert.go | 20 +++++ .../migrations/001_inital_database.sql | 76 +++++++++++-------- pkg/database/postgres.go | 3 +- pkg/models/pgModels/orm.go | 12 +++ pkg/models/pgModels/post.go | 4 + pkg/models/pgModels/tag.go | 22 ++++-- 9 files changed, 140 insertions(+), 38 deletions(-) create mode 100644 internal/postgres/tag.go diff --git a/go.mod b/go.mod index a2ceed4..9dcb619 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect + github.com/matoous/go-nanoid/v2 v2.1.0 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.18.0 // indirect diff --git a/go.sum b/go.sum index 7d29fd6..f00d304 100644 --- a/go.sum +++ b/go.sum @@ -23,6 +23,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/matoous/go-nanoid/v2 v2.1.0 h1:P64+dmq21hhWdtvZfEAofnvJULaRR1Yib0+PnU669bE= +github.com/matoous/go-nanoid/v2 v2.1.0/go.mod h1:KlbGNQ+FhrUNIHUxZdL63t7tl4LaPkZNpUULS8H4uVM= github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/neo4j/neo4j-go-driver/v5 v5.17.0 h1:Bdqg1Y8Hd3uLYToXtBjysDYXTdMiP7zeUNUEwfbJkSo= diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go new file mode 100644 index 0000000..1dc97b1 --- /dev/null +++ b/internal/postgres/tag.go @@ -0,0 +1,38 @@ +package postgres + +import ( + "context" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" + log "github.com/sirupsen/logrus" + "gorm.io/gorm" +) + +func CreateTagNodeWitRelation(ctx context.Context, db *gorm.DB, PostID models.AnthrovePostID, tag *pgModels.Tag) error { + + resultTag := db.WithContext(ctx).Where(tag).FirstOrCreate(tag) + + if resultTag.Error != nil { + return resultTag.Error + } + + pgPost := pgModels.Post{ + BaseModel: pgModels.BaseModel{ + ID: string(PostID), + }, + } + + err := db.WithContext(ctx).Model(pgPost).Association("Tags").Append(tag) + + if err != nil { + return err + } + + log.WithFields(log.Fields{ + "anthrove_post_id": PostID, + "tag_name": tag.Name, + "tag_type": tag.Type, + }).Trace("database: created tag node") + + return nil +} diff --git a/internal/utils/modelConvert.go b/internal/utils/modelConvert.go index cc75258..080af20 100644 --- a/internal/utils/modelConvert.go +++ b/internal/utils/modelConvert.go @@ -1,6 +1,7 @@ package utils import ( + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" ) @@ -25,3 +26,22 @@ func PostgresConvertToAnthroveSource(pgSource *pgModels.Source) *graphModels.Ant return graphSource } + +// GraphConvertTag converts a graphModels.AnthroveTag to a pgModels.Tag +func GraphConvertTag(graphTag *graphModels.AnthroveTag) *pgModels.Tag { + pgTag := &pgModels.Tag{ + Name: graphTag.Name, + Type: models.TagType(graphTag.Type), + } + return pgTag +} + +// PostgresConvertToAnthroveTag converts a pgModels.Tag to a graphModels.AnthroveTag +func PostgresConvertToAnthroveTag(pgTag *pgModels.Tag) *graphModels.AnthroveTag { + graphTag := &graphModels.AnthroveTag{ + Name: pgTag.Name, + Type: string(pgTag.Type), + } + + return graphTag +} diff --git a/pkg/database/migrations/001_inital_database.sql b/pkg/database/migrations/001_inital_database.sql index 00fcf9c..66770a1 100644 --- a/pkg/database/migrations/001_inital_database.sql +++ b/pkg/database/migrations/001_inital_database.sql @@ -1,9 +1,3 @@ --- TODO: Add the following fields where its defined in the model --- created_at --- updated_at --- deleted_at - - -- +migrate Up CREATE TYPE Rating AS ENUM ( 'safe', @@ -23,29 +17,39 @@ CREATE TYPE TagType AS ENUM ( CREATE TABLE "Post" ( - id VARCHAR(25) UNIQUE PRIMARY KEY, + id CHAR(25) UNIQUE PRIMARY KEY, rating Rating, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP NULL NULL ); CREATE TABLE "Source" ( - id VARCHAR(25) UNIQUE PRIMARY KEY, - display_name TEXT, - icon TEXT, - domain TEXT NOT NULL UNIQUE + id CHAR(25) UNIQUE PRIMARY KEY, + display_name TEXT NULL, + icon TEXT NULL, + domain TEXT NOT NULL UNIQUE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP NULL ); CREATE TABLE "Tag" ( - name TEXT PRIMARY KEY, - type TagType + name TEXT PRIMARY KEY, + tag_type TagType, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP NULL ); CREATE TABLE "User" ( id TEXT UNIQUE PRIMARY KEY, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP NULL ); CREATE TABLE "PostReference" @@ -59,20 +63,22 @@ CREATE TABLE "PostReference" CREATE TABLE "TagAlias" ( - name TEXT PRIMARY KEY, - tag_id TEXT REFERENCES "Tag" (name) + name TEXT PRIMARY KEY, + tag_id TEXT REFERENCES "Tag" (name), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE "TagGroup" ( - name TEXT PRIMARY KEY, - tag_id TEXT REFERENCES "Tag" (name) + name TEXT PRIMARY KEY, + tag_id TEXT REFERENCES "Tag" (name), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE "UserFavorites" ( - user_id TEXT REFERENCES "User" (id), - post_id TEXT REFERENCES "Post" (id), + user_id TEXT UNIQUE REFERENCES "User" (id), + post_id TEXT UNIQUE REFERENCES "Post" (id), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (user_id, post_id) ); @@ -83,18 +89,26 @@ CREATE TABLE "UserSource" source_id TEXT REFERENCES "Source" (id), account_username TEXT, account_id TEXT, - PRIMARY KEY (user_id, source_id) + PRIMARY KEY (user_id, source_id), + UNIQUE (account_username, account_id) +); + +CREATE TABLE "post_tags" +( + post_id TEXT REFERENCES "Post" (id), + tag_name TEXT REFERENCES "Tag" (name), + PRIMARY KEY (post_id, tag_name) ); -- +migrate Down DROP TYPE Rating; DROP TYPE TagType; -DROP TYPE Post; -DROP TYPE Source; -DROP TYPE Tag; -DROP TYPE User; -DROP TYPE PostReference; -DROP TYPE TagAlias; -DROP TYPE TagGroup; -DROP TYPE UserFavorites; -DROP TYPE UserSource; \ No newline at end of file +DROP TABLE Post; +DROP TABLE Source; +DROP TABLE Tag; +DROP TABLE User; +DROP TABLE PostReference; +DROP TABLE TagAlias; +DROP TABLE TagGroup; +DROP TABLE UserFavorites; +DROP TABLE UserSource; \ No newline at end of file diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 5ed0afe..f1d8402 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -68,8 +68,7 @@ func (p *postgresqlConnection) AddPost(ctx context.Context, anthrovePost *graphM } func (p *postgresqlConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *graphModels.AnthroveTag) error { - //TODO implement me - panic("implement me") + return postgres.CreateTagNodeWitRelation(ctx, p.db, anthrovePostID, utils.GraphConvertTag(anthroveTag)) } func (p *postgresqlConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error { diff --git a/pkg/models/pgModels/orm.go b/pkg/models/pgModels/orm.go index bea5f1b..11aafa4 100644 --- a/pkg/models/pgModels/orm.go +++ b/pkg/models/pgModels/orm.go @@ -1,6 +1,7 @@ package pgModels import ( + gonanoid "github.com/matoous/go-nanoid/v2" "gorm.io/gorm" "time" ) @@ -11,3 +12,14 @@ type BaseModel struct { UpdatedAt time.Time DeletedAt gorm.DeletedAt `gorm:"index"` } + +func (base *BaseModel) BeforeCreate(db *gorm.DB) error { + id, err := gonanoid.New() + if err != nil { + return err + } + + base.ID = id + + return nil +} diff --git a/pkg/models/pgModels/post.go b/pkg/models/pgModels/post.go index d2dd980..d5ea588 100644 --- a/pkg/models/pgModels/post.go +++ b/pkg/models/pgModels/post.go @@ -12,3 +12,7 @@ type Post struct { Favorites []UserFavorite `gorm:"foreignKey:PostID"` References []PostReference `gorm:"foreignKey:PostID"` } + +func (Post) TableName() string { + return "Post" +} diff --git a/pkg/models/pgModels/tag.go b/pkg/models/pgModels/tag.go index 406f744..7538ac9 100644 --- a/pkg/models/pgModels/tag.go +++ b/pkg/models/pgModels/tag.go @@ -4,11 +4,15 @@ import "git.dragse.it/anthrove/otter-space-sdk/pkg/models" // Tag models type Tag struct { - Name string `gorm:"primaryKey"` - Type models.TagType - Aliases []TagAlias `gorm:"foreignKey:TagID"` - Groups []TagGroup `gorm:"foreignKey:TagID"` - Posts []Post `gorm:"many2many:post_tags;"` + Name string `gorm:"primaryKey"` + Type models.TagType `gorm:"column:tag_type"` + Aliases []TagAlias `gorm:"foreignKey:TagID"` + Groups []TagGroup `gorm:"foreignKey:TagID"` + Posts []Post `gorm:"many2many:post_tags;"` +} + +func (Tag) TableName() string { + return "Tag" } // TagAlias model @@ -17,8 +21,16 @@ type TagAlias struct { TagID string } +func (TagAlias) TableName() string { + return "TagAlias" +} + // TagGroup model type TagGroup struct { Name string `gorm:"primaryKey"` TagID string } + +func (TagGroup) TableName() string { + return "TagGroup" +} -- 2.45.1 From a60805fccfcaf0454cf235565687e921ad7cc2c2 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 12:06:58 +0200 Subject: [PATCH 019/124] feat(postgres): added console debug option --- pkg/database/postgres.go | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index f1d8402..e4ee38a 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -5,7 +5,6 @@ import ( "database/sql" "embed" "fmt" - "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" "git.dragse.it/anthrove/otter-space-sdk/internal/utils" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" @@ -21,12 +20,14 @@ import ( var embedMigrations embed.FS type postgresqlConnection struct { - db *gorm.DB + db *gorm.DB + debug bool } -func NewPostgresqlConnection() OtterSpace { +func NewPostgresqlConnection(debugOutput bool) OtterSpace { return &postgresqlConnection{ - db: nil, + db: nil, + debug: debugOutput, } } @@ -170,12 +171,15 @@ func (p *postgresqlConnection) migrateDatabase(connectionString string) error { if err != nil { return fmt.Errorf("postgres migration: %v", err) } - if n != 0 { - log.Tracef("postgres migration: applied %d migrations!", n) - } else { - log.Trace("postgres migration: nothing to migrate") + if p.debug { + if n != 0 { + log.Infof("postgres migration: applied %d migrations!", n) + } else { + log.Info("postgres migration: nothing to migrate") + + } } return nil -- 2.45.1 From aae7fc78e00ccb7a6b72922b76e3697e6e76dc46 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 12:24:14 +0200 Subject: [PATCH 020/124] feat(postgres): added image urls to the database --- .../migrations/001_inital_database.sql | 21 +++++++++++-------- pkg/models/pgModels/postReference.go | 11 ++++++---- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/pkg/database/migrations/001_inital_database.sql b/pkg/database/migrations/001_inital_database.sql index 66770a1..c78c150 100644 --- a/pkg/database/migrations/001_inital_database.sql +++ b/pkg/database/migrations/001_inital_database.sql @@ -27,9 +27,9 @@ CREATE TABLE "Post" CREATE TABLE "Source" ( id CHAR(25) UNIQUE PRIMARY KEY, - display_name TEXT NULL, - icon TEXT NULL, - domain TEXT NOT NULL UNIQUE, + display_name TEXT NULL, + icon TEXT NULL, + domain TEXT NOT NULL UNIQUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, deleted_at TIMESTAMP NULL @@ -54,10 +54,13 @@ CREATE TABLE "User" CREATE TABLE "PostReference" ( - post_id TEXT REFERENCES "Post" (id), - source_id TEXT REFERENCES "Source" (id), - url TEXT NOT NULL UNIQUE, - source_post_id TEXT, + post_id TEXT REFERENCES "Post" (id), + source_id TEXT REFERENCES "Source" (id), + url TEXT NOT NULL UNIQUE, + full_file_url TEXT, + preview_file_url TEXT, + sample_file_url TEXT, + source_post_id TEXT, PRIMARY KEY (post_id, source_id) ); @@ -77,8 +80,8 @@ CREATE TABLE "TagGroup" CREATE TABLE "UserFavorites" ( - user_id TEXT UNIQUE REFERENCES "User" (id), - post_id TEXT UNIQUE REFERENCES "Post" (id), + user_id TEXT UNIQUE REFERENCES "User" (id), + post_id TEXT UNIQUE REFERENCES "Post" (id), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (user_id, post_id) ); diff --git a/pkg/models/pgModels/postReference.go b/pkg/models/pgModels/postReference.go index ae4574c..1163731 100644 --- a/pkg/models/pgModels/postReference.go +++ b/pkg/models/pgModels/postReference.go @@ -1,8 +1,11 @@ package pgModels type PostReference struct { - PostID string `gorm:"primaryKey"` - SourceID string `gorm:"primaryKey"` - URL string `gorm:"not null;unique"` - SourcePostID string + PostID string `gorm:"primaryKey"` + SourceID string `gorm:"primaryKey"` + URL string `gorm:"not null;unique"` + SourcePostID string + FullFileURL string + PreviewFileURL string + SampleFileURL string } -- 2.45.1 From 011f4d1c2a39e78e0def2a8795939fa88cd5717f Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 13:05:07 +0200 Subject: [PATCH 021/124] feat(postgres): added tag create and function to get all tags --- go.mod | 3 ++- go.sum | 6 ++++-- internal/postgres/tag.go | 14 ++++++++++++++ internal/utils/modelConvert.go | 13 +++++++++++++ pkg/database/postgres.go | 5 +++-- 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 9dcb619..4b598af 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,9 @@ module git.dragse.it/anthrove/otter-space-sdk go 1.22.0 require ( + github.com/brianvoe/gofakeit/v7 v7.0.3 github.com/lib/pq v1.10.7 + github.com/matoous/go-nanoid/v2 v2.1.0 github.com/neo4j/neo4j-go-driver/v5 v5.17.0 github.com/rubenv/sql-migrate v1.6.1 github.com/sirupsen/logrus v1.9.3 @@ -19,7 +21,6 @@ require ( github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - github.com/matoous/go-nanoid/v2 v2.1.0 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.18.0 // indirect diff --git a/go.sum b/go.sum index f00d304..9cd0cd1 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/brianvoe/gofakeit/v7 v7.0.3 h1:tGCt+eYfhTMWE1ko5G2EO1f/yE44yNpIwUb4h32O0wo= +github.com/brianvoe/gofakeit/v7 v7.0.3/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -42,8 +44,8 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 1dc97b1..d873506 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -36,3 +36,17 @@ func CreateTagNodeWitRelation(ctx context.Context, db *gorm.DB, PostID models.An return nil } + +func GetTags(ctx context.Context, db *gorm.DB) ([]pgModels.Tag, error) { + var tags []pgModels.Tag + result := db.WithContext(ctx).Find(&tags) + if result.Error != nil { + return nil, result.Error + } + + log.WithFields(log.Fields{ + "tag_amount": len(tags), + }).Trace("database: got tags") + + return tags, nil +} diff --git a/internal/utils/modelConvert.go b/internal/utils/modelConvert.go index 080af20..29a4995 100644 --- a/internal/utils/modelConvert.go +++ b/internal/utils/modelConvert.go @@ -45,3 +45,16 @@ func PostgresConvertToAnthroveTag(pgTag *pgModels.Tag) *graphModels.AnthroveTag return graphTag } + +func ConvertToTagsWithFrequency(tags []pgModels.Tag) []graphModels.TagsWithFrequency { + var tagsWithFrequency []graphModels.TagsWithFrequency + for _, tag := range tags { + graphTag := PostgresConvertToAnthroveTag(&tag) + tagsWithFrequency = append(tagsWithFrequency, graphModels.TagsWithFrequency{ + Frequency: 0, + Tags: *graphTag, + }) + } + + return tagsWithFrequency +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index e4ee38a..887a62a 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -138,8 +138,9 @@ func (p *postgresqlConnection) GetUserTagsTroughFavedPosts(ctx context.Context, } func (p *postgresqlConnection) GetAllTags(ctx context.Context) ([]graphModels.TagsWithFrequency, error) { - //TODO implement me - panic("implement me") + tags, err := postgres.GetTags(ctx, p.db) + + return utils.ConvertToTagsWithFrequency(tags), err } func (p *postgresqlConnection) GetAllSources(ctx context.Context) ([]graphModels.AnthroveSource, error) { -- 2.45.1 From 8d655e991fbca1792bef9ecd80b93ef9d04f598a Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 13:19:55 +0200 Subject: [PATCH 022/124] feat(postgres): added LinkPostWithSource --- internal/postgres/relationships.go | 39 ++++++++++++++++++++++++++++++ pkg/database/postgres.go | 3 +-- 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 internal/postgres/relationships.go diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go new file mode 100644 index 0000000..b3170d4 --- /dev/null +++ b/internal/postgres/relationships.go @@ -0,0 +1,39 @@ +package postgres + +import ( + "context" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" + log "github.com/sirupsen/logrus" + "gorm.io/gorm" +) + +func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string) error { + var post pgModels.Post + var source pgModels.Source + + // Find the post + err := db.WithContext(ctx).Where("id = ?", anthrovePostID).First(&post).Error + if err != nil { + return err + } + + // Find the source + err = db.WithContext(ctx).Where("domain = ?", anthroveSourceDomain).First(&source).Error + if err != nil { + return err + } + + // Establish the relationship + err = db.WithContext(ctx).Model(&post).Association("Sources").Append(&source) + if err != nil { + return err + } + + log.WithFields(log.Fields{ + "anthrove_post_id": anthrovePostID, + "anthrove_source_domain": anthroveSourceDomain, + }).Trace("database: created anthrove post to source link") + + return nil +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 887a62a..bd57a64 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -73,8 +73,7 @@ func (p *postgresqlConnection) AddTagWithRelationToPost(ctx context.Context, ant } func (p *postgresqlConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error { - //TODO implement me - panic("implement me") + return postgres.EstablishAnthrovePostToSourceLink(ctx, p.db, anthrovePostID, anthroveSourceDomain) } func (p *postgresqlConnection) LinkUserWithPost(ctx context.Context, anthroveUser *graphModels.AnthroveUser, anthrovePost *graphModels.AnthrovePost) error { -- 2.45.1 From a430c3b5820ecd31a446ea335d42e76f83f04081 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 13:22:52 +0200 Subject: [PATCH 023/124] feat(postgres): added LinkUserWithPost --- internal/postgres/relationships.go | 19 +++++++++++++++++++ pkg/database/postgres.go | 3 +-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index b3170d4..1a07396 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -37,3 +37,22 @@ func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrov return nil } + +func EstablishUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error { + userFavorite := pgModels.UserFavorite{ + UserID: string(anthroveUserID), + PostID: string(anthrovePostID), + } + + err := db.WithContext(ctx).Create(&userFavorite).Error + if err != nil { + return err + } + + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + "anthrove_post_id": anthrovePostID, + }).Trace("database: created user to post link") + + return nil +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index bd57a64..a4a9008 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -77,8 +77,7 @@ func (p *postgresqlConnection) LinkPostWithSource(ctx context.Context, anthroveP } func (p *postgresqlConnection) LinkUserWithPost(ctx context.Context, anthroveUser *graphModels.AnthroveUser, anthrovePost *graphModels.AnthrovePost) error { - //TODO implement me - panic("implement me") + return postgres.EstablishUserToPostLink(ctx, p.db, anthroveUser.UserID, anthrovePost.PostID) } func (p *postgresqlConnection) CheckUserPostLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) { -- 2.45.1 From ad3a43366be52cd2359cff75bcaff830d93d267a Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 13:25:54 +0200 Subject: [PATCH 024/124] feat(postgres): added CheckUserPostLink --- internal/postgres/relationships.go | 18 ++++++++++++++++++ pkg/database/postgres.go | 3 +-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index 1a07396..fd855eb 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -56,3 +56,21 @@ func EstablishUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID mo return nil } + +func CheckUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) (bool, error) { + var count int64 + err := db.WithContext(ctx).Model(&pgModels.UserFavorite{}).Where("user_id = ? AND post_id = ?", string(anthroveUserID), string(anthrovePostID)).Count(&count).Error + if err != nil { + return false, err + } + + exists := count > 0 + + log.WithFields(log.Fields{ + "relationship_exists": exists, + "relationship_anthrove_user_id": anthroveUserID, + "relationship_anthrove_post_id": anthrovePostID, + }).Trace("database: checked user post relationship") + + return exists, nil +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index a4a9008..661a884 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -81,8 +81,7 @@ func (p *postgresqlConnection) LinkUserWithPost(ctx context.Context, anthroveUse } func (p *postgresqlConnection) CheckUserPostLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) { - //TODO implement me - panic("implement me") + return postgres.CheckUserToPostLink(ctx, p.db, anthroveUserID, models.AnthrovePostID(sourcePostID)) } func (p *postgresqlConnection) CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *graphModels.AnthrovePost) (*graphModels.AnthrovePost, bool, error) { -- 2.45.1 From bd22ed3f7933a9990be34164f259b5fb1f9121f0 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 13:29:53 +0200 Subject: [PATCH 025/124] feat(postgres): added AddPost --- internal/postgres/post.go | 30 ++++++++++++++++++++++++++++++ pkg/database/postgres.go | 3 +-- 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 internal/postgres/post.go diff --git a/internal/postgres/post.go b/internal/postgres/post.go new file mode 100644 index 0000000..ff3d0d3 --- /dev/null +++ b/internal/postgres/post.go @@ -0,0 +1,30 @@ +package postgres + +import ( + "context" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" + log "github.com/sirupsen/logrus" + "gorm.io/gorm" +) + +func CreateAnthrovePostNode(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, anthroveRating models.Rating) error { + post := pgModels.Post{ + BaseModel: pgModels.BaseModel{ + ID: string(anthrovePostID), + }, + Rating: anthroveRating, + } + + err := db.WithContext(ctx).Create(&post).Error + if err != nil { + return err + } + + log.WithFields(log.Fields{ + "anthrove_post_id": anthrovePostID, + "anthrove_post_rating": anthroveRating, + }).Trace("database: created anthrove post") + + return nil +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 661a884..bc4b494 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -64,8 +64,7 @@ func (p *postgresqlConnection) AddSource(ctx context.Context, anthroveSource *gr } func (p *postgresqlConnection) AddPost(ctx context.Context, anthrovePost *graphModels.AnthrovePost) error { - //TODO implement me - panic("implement me") + return postgres.CreateAnthrovePostNode(ctx, p.db, anthrovePost.PostID, anthrovePost.Rating) } func (p *postgresqlConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *graphModels.AnthroveTag) error { -- 2.45.1 From 78777ce7be48fb302784e7f93b1107cd42b4b80a Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 13:57:03 +0200 Subject: [PATCH 026/124] feat(postgres): partially added Check heckPostNodeExistsBy --- internal/postgres/post.go | 30 ++++++++++++++++++++++++++++++ pkg/database/postgres.go | 16 ++++++++++------ pkg/models/pgModels/orm.go | 13 ++++++++----- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/internal/postgres/post.go b/internal/postgres/post.go index ff3d0d3..02ac938 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -28,3 +28,33 @@ func CreateAnthrovePostNode(ctx context.Context, db *gorm.DB, anthrovePostID mod return nil } + +func CheckIfAnthrovePostNodeExistsByAnthroveID(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID) (bool, error) { + return executeCheckQuery(ctx, db, "id = ?", string(anthrovePostID)) +} + +func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (bool, error) { + return executeCheckQuery(ctx, db, "url = ?", sourceURL) +} + +func CheckIfAnthrovePostNodeExistsBySourceID(ctx context.Context, db *gorm.DB, sourceID string) (bool, error) { + return executeCheckQuery(ctx, db, "source_id = ?", sourceID) +} + +func executeCheckQuery(ctx context.Context, db *gorm.DB, query string, args ...interface{}) (bool, error) { + var count int64 + err := db.WithContext(ctx).Model(&pgModels.Post{}).Where(query, args...).Count(&count).Error + if err != nil { + return false, err + } + + exists := count > 0 + + log.WithFields(log.Fields{ + "query": query, + "args": args, + "exists": exists, + }).Trace("database: executed check query") + + return exists, nil +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index bc4b494..a37c2e0 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -84,18 +84,22 @@ func (p *postgresqlConnection) CheckUserPostLink(ctx context.Context, anthroveUs } func (p *postgresqlConnection) CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *graphModels.AnthrovePost) (*graphModels.AnthrovePost, bool, error) { - //TODO implement me - panic("implement me") + exists, err := postgres.CheckIfAnthrovePostNodeExistsByAnthroveID(ctx, p.db, anthrovePost.PostID) + return anthrovePost, exists, err } +// CheckPostNodeExistsBySourceURL NOT WORKING! TODO! func (p *postgresqlConnection) CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*graphModels.AnthrovePost, bool, error) { - //TODO implement me - panic("implement me") + var post graphModels.AnthrovePost + exists, err := postgres.CheckIfAnthrovePostNodeExistsBySourceURL(ctx, p.db, sourceUrl) + return &post, exists, err } +// CheckPostNodeExistsBySourceID NOT WORKING! TODO! func (p *postgresqlConnection) CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*graphModels.AnthrovePost, bool, error) { - //TODO implement me - panic("implement me") + var post graphModels.AnthrovePost + exists, err := postgres.CheckIfAnthrovePostNodeExistsBySourceID(ctx, p.db, sourcePostID) + return &post, exists, err } func (p *postgresqlConnection) GetUserFavoriteCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) { diff --git a/pkg/models/pgModels/orm.go b/pkg/models/pgModels/orm.go index 11aafa4..c637fa5 100644 --- a/pkg/models/pgModels/orm.go +++ b/pkg/models/pgModels/orm.go @@ -14,12 +14,15 @@ type BaseModel struct { } func (base *BaseModel) BeforeCreate(db *gorm.DB) error { - id, err := gonanoid.New() - if err != nil { - return err - } - base.ID = id + if base.ID == "" { + id, err := gonanoid.New() + if err != nil { + return err + } + + base.ID = id + } return nil } -- 2.45.1 From c04e382ee5f5b2b2a752969f1c00855e75f0e03b Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 14:48:23 +0200 Subject: [PATCH 027/124] feat(postgres): added AddUserWithRelationToSource --- internal/postgres/user.go | 61 +++++++++++++++++++++++++++++++++++++++ pkg/database/postgres.go | 3 +- 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 internal/postgres/user.go diff --git a/internal/postgres/user.go b/internal/postgres/user.go new file mode 100644 index 0000000..f24191d --- /dev/null +++ b/internal/postgres/user.go @@ -0,0 +1,61 @@ +package postgres + +import ( + "context" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" + log "github.com/sirupsen/logrus" + "gorm.io/gorm" +) + +func CreateUserNodeWithSourceRelation(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error { + user := pgModels.User{ + BaseModel: pgModels.BaseModel{ + ID: string(anthroveUserID), + }, + } + + if err := db.WithContext(ctx).FirstOrCreate(&user).Error; err != nil { + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + }).Error("database: failed to find or create user") + return err + } + + source := pgModels.Source{ + Domain: sourceDomain, + } + + if err := db.WithContext(ctx).Where(&source).First(&source).Error; err != nil { + log.WithFields(log.Fields{ + "source_domain": sourceDomain, + }).Error("database: failed to find source") + return err + } + + userSource := pgModels.UserSource{ + UserID: user.ID, + SourceID: source.ID, + AccountUsername: username, + AccountID: userID, + } + + if err := db.WithContext(ctx).Create(&userSource).Error; err != nil { + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + "source_domain": sourceDomain, + "account_username": username, + "account_id": userID, + }).Error("database: failed to create user-source relationship") + return err + } + + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + "source_domain": sourceDomain, + "account_username": username, + "account_id": userID, + }).Trace("database: created user-source relationship") + + return nil +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index a37c2e0..13fe10d 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -54,8 +54,7 @@ func (p *postgresqlConnection) Connect(_ context.Context, endpoint string, usern } func (p *postgresqlConnection) AddUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error { - //TODO implement me - panic("implement me") + return postgres.CreateUserNodeWithSourceRelation(ctx, p.db, anthroveUserID, userID, sourceDomain, userID) } func (p *postgresqlConnection) AddSource(ctx context.Context, anthroveSource *graphModels.AnthroveSource) error { -- 2.45.1 From 4f8e54f09a0b3dc05784d535c8f1e375a82d67a7 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 14:50:29 +0200 Subject: [PATCH 028/124] feat(postgres): added GetUserFavoriteCount --- internal/postgres/user.go | 18 ++++++++++++++++++ pkg/database/postgres.go | 3 +-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/internal/postgres/user.go b/internal/postgres/user.go index f24191d..acd9695 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -59,3 +59,21 @@ func CreateUserNodeWithSourceRelation(ctx context.Context, db *gorm.DB, anthrove return nil } + +func GetUserFavoritesCount(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) (int64, error) { + var count int64 + err := db.WithContext(ctx).Model(&pgModels.UserFavorite{}).Where("user_id = ?", string(anthroveUserID)).Count(&count).Error + if err != nil { + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + }).Error("database: failed to get user favorites count") + return 0, err + } + + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + "anthrove_user_fav_count": count, + }).Trace("database: got user favorite count") + + return count, nil +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 13fe10d..883de13 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -102,8 +102,7 @@ func (p *postgresqlConnection) CheckPostNodeExistsBySourceID(ctx context.Context } func (p *postgresqlConnection) GetUserFavoriteCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) { - //TODO implement me - panic("implement me") + return postgres.GetUserFavoritesCount(ctx, p.db, anthroveUserID) } func (p *postgresqlConnection) GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]graphModels.AnthroveUserRelationship, error) { -- 2.45.1 From 16d5a381df9ba7c041bfdd9c55f2c7203c5e35f5 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 15:03:34 +0200 Subject: [PATCH 029/124] feat(postgres): added GetUserSourceLinks --- internal/postgres/user.go | 41 +++++++++++++++++++++++++++++++++++++++ pkg/database/postgres.go | 3 +-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/internal/postgres/user.go b/internal/postgres/user.go index acd9695..a2e60fe 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -3,6 +3,7 @@ package postgres import ( "context" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" log "github.com/sirupsen/logrus" "gorm.io/gorm" @@ -77,3 +78,43 @@ func GetUserFavoritesCount(ctx context.Context, db *gorm.DB, anthroveUserID mode return count, nil } + +func GetUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) (map[string]graphModels.AnthroveUserRelationship, error) { + var userSources []pgModels.UserSource + userSourceMap := make(map[string]graphModels.AnthroveUserRelationship) + + err := db.WithContext(ctx).Model(&pgModels.UserSource{}).Where("user_id = ?", string(anthroveUserID)).Find(&userSources).Error + if err != nil { + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + }).Error("database: failed to get user source link") + return nil, err + } + + for _, userSource := range userSources { + var source pgModels.Source + err = db.WithContext(ctx).Model(&pgModels.Source{}).Where("id = ?", userSource.SourceID).First(&source).Error + if err != nil { + log.WithFields(log.Fields{ + "source_id": userSource.SourceID, + }).Error("database: failed to get source") + return nil, err + } + + userSourceMap[source.DisplayName] = graphModels.AnthroveUserRelationship{ + UserID: userSource.AccountID, + Username: userSource.AccountUsername, + Source: graphModels.AnthroveSource{ + DisplayName: source.DisplayName, + Domain: source.Domain, + Icon: source.Icon, + }, + } + } + + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + }).Trace("database: got user source link") + + return userSourceMap, nil +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 883de13..7d095b0 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -106,8 +106,7 @@ func (p *postgresqlConnection) GetUserFavoriteCount(ctx context.Context, anthrov } func (p *postgresqlConnection) GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]graphModels.AnthroveUserRelationship, error) { - //TODO implement me - panic("implement me") + return postgres.GetUserSourceLink(ctx, p.db, anthroveUserID) } func (p *postgresqlConnection) GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]graphModels.AnthroveUserRelationship, error) { -- 2.45.1 From bbd08b9a2f17aa77342a70280730aa05878ac965 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 15:04:45 +0200 Subject: [PATCH 030/124] feat(postgres): added GetSpecifiedUserSourceLink --- internal/postgres/user.go | 42 +++++++++++++++++++++++++++++++++++++++ pkg/database/postgres.go | 3 +-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/internal/postgres/user.go b/internal/postgres/user.go index a2e60fe..b27f55b 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -118,3 +118,45 @@ func GetUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID models.A return userSourceMap, nil } + +func GetSpecifiedUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]graphModels.AnthroveUserRelationship, error) { + var userSources []pgModels.UserSource + userSourceMap := make(map[string]graphModels.AnthroveUserRelationship) + + err := db.WithContext(ctx).Model(&pgModels.UserSource{}).Joins("Source").Where("user_id = ? AND display_name = ?", string(anthroveUserID), sourceDisplayName).Find(&userSources).Error + if err != nil { + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + "source_display_name": sourceDisplayName, + }).Error("database: failed to get specified user source link") + return nil, err + } + + for _, userSource := range userSources { + var source pgModels.Source + err = db.WithContext(ctx).Model(&pgModels.Source{}).Where("id = ?", userSource.SourceID).First(&source).Error + if err != nil { + log.WithFields(log.Fields{ + "source_id": userSource.SourceID, + }).Error("database: failed to get source") + return nil, err + } + + userSourceMap[source.DisplayName] = graphModels.AnthroveUserRelationship{ + UserID: userSource.AccountID, + Username: userSource.AccountUsername, + Source: graphModels.AnthroveSource{ + DisplayName: source.DisplayName, + Domain: source.Domain, + Icon: source.Icon, + }, + } + } + + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + "source_display_name": sourceDisplayName, + }).Trace("database: got specified user source link") + + return userSourceMap, nil +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 7d095b0..b738d79 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -110,8 +110,7 @@ func (p *postgresqlConnection) GetUserSourceLinks(ctx context.Context, anthroveU } func (p *postgresqlConnection) GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]graphModels.AnthroveUserRelationship, error) { - //TODO implement me - panic("implement me") + return postgres.GetSpecifiedUserSourceLink(ctx, p.db, anthroveUserID, sourceDisplayName) } func (p *postgresqlConnection) GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*graphModels.AnthroveUser, error) { -- 2.45.1 From 4cdd4450d52f5874e6549efdf76dd36b7ba65540 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 15:07:23 +0200 Subject: [PATCH 031/124] feat(postgres): added GetAnthroveUser --- internal/postgres/user.go | 51 +++++++++++++++++++++++++++++++++++++++ pkg/database/postgres.go | 3 +-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/internal/postgres/user.go b/internal/postgres/user.go index b27f55b..d250f1f 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -160,3 +160,54 @@ func GetSpecifiedUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID return userSourceMap, nil } + +func GetAnthroveUser(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) (*graphModels.AnthroveUser, error) { + var user pgModels.User + var userSources []pgModels.UserSource + anthroveUser := &graphModels.AnthroveUser{ + UserID: anthroveUserID, + } + + err := db.WithContext(ctx).First(&user, "id = ?", string(anthroveUserID)).Error + if err != nil { + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + }).Error("database: failed to get user") + return nil, err + } + + err = db.WithContext(ctx).Model(&pgModels.UserSource{}).Where("user_id = ?", string(anthroveUserID)).Find(&userSources).Error + if err != nil { + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + }).Error("database: failed to get user sources") + return nil, err + } + + for _, userSource := range userSources { + var source pgModels.Source + err = db.WithContext(ctx).Model(&pgModels.Source{}).Where("id = ?", userSource.SourceID).First(&source).Error + if err != nil { + log.WithFields(log.Fields{ + "source_id": userSource.SourceID, + }).Error("database: failed to get source") + return nil, err + } + + anthroveUser.Relationship = append(anthroveUser.Relationship, graphModels.AnthroveUserRelationship{ + UserID: userSource.AccountID, + Username: userSource.AccountUsername, + Source: graphModels.AnthroveSource{ + DisplayName: source.DisplayName, + Domain: source.Domain, + Icon: source.Icon, + }, + }) + } + + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + }).Trace("database: got anthrove user") + + return anthroveUser, nil +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index b738d79..eea7600 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -114,8 +114,7 @@ func (p *postgresqlConnection) GetSpecifiedUserSourceLink(ctx context.Context, a } func (p *postgresqlConnection) GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*graphModels.AnthroveUser, error) { - //TODO implement me - panic("implement me") + return postgres.GetAnthroveUser(ctx, p.db, anthroveUserID) } func (p *postgresqlConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) { -- 2.45.1 From 6268a594cf7cace2e110fd7ab08e93cdc05cab76 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 15:09:11 +0200 Subject: [PATCH 032/124] feat(postgres): added GetAllAnthroveUserIDs --- internal/postgres/user.go | 21 +++++++++++++++++++++ pkg/database/postgres.go | 3 +-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/internal/postgres/user.go b/internal/postgres/user.go index d250f1f..f149d14 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -211,3 +211,24 @@ func GetAnthroveUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Ant return anthroveUser, nil } + +func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveUserID, error) { + var users []pgModels.User + var userIDs []models.AnthroveUserID + + err := db.WithContext(ctx).Model(&pgModels.User{}).Find(&users).Error + if err != nil { + log.Error("database: failed to get all anthrove user IDs") + return nil, err + } + + for _, user := range users { + userIDs = append(userIDs, models.AnthroveUserID(user.ID)) + } + + log.WithFields(log.Fields{ + "anthrove_user_id_count": len(userIDs), + }).Trace("database: got all anthrove user IDs") + + return userIDs, nil +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index eea7600..7395bdf 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -118,8 +118,7 @@ func (p *postgresqlConnection) GetAnthroveUser(ctx context.Context, anthroveUser } func (p *postgresqlConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) { - //TODO implement me - panic("implement me") + return postgres.GetAllAnthroveUserIDs(ctx, p.db) } func (p *postgresqlConnection) GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*graphModels.FavoriteList, error) { -- 2.45.1 From 8cde1235ad034b43a679727aa9eb9f0498050557 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 15:11:13 +0200 Subject: [PATCH 033/124] feat(postgres): added GetUserFavoritePostsWithPagination --- internal/postgres/user.go | 40 +++++++++++++++++++++++++++++++++++++++ pkg/database/postgres.go | 3 +-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/internal/postgres/user.go b/internal/postgres/user.go index f149d14..676bfa4 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -232,3 +232,43 @@ func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveU return userIDs, nil } + +func GetUserFavoriteNodeWithPagination(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, skip int, limit int) (*graphModels.FavoriteList, error) { + var userFavorites []pgModels.UserFavorite + var favoritePosts []graphModels.FavoritePost + + err := db.WithContext(ctx).Model(&pgModels.UserFavorite{}).Where("user_id = ?", string(anthroveUserID)).Offset(skip).Limit(limit).Find(&userFavorites).Error + if err != nil { + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + "skip": skip, + "limit": limit, + }).Error("database: failed to get user favorites with pagination") + return nil, err + } + + for _, userFavorite := range userFavorites { + var post pgModels.Post + err = db.WithContext(ctx).Model(&pgModels.Post{}).Where("id = ?", userFavorite.PostID).First(&post).Error + if err != nil { + log.WithFields(log.Fields{ + "post_id": userFavorite.PostID, + }).Error("database: failed to get post") + return nil, err + } + + favoritePosts = append(favoritePosts, graphModels.FavoritePost{ + AnthrovePost: graphModels.AnthrovePost{ + PostID: models.AnthrovePostID(post.ID), + Rating: post.Rating, + }, + }) + } + + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + "anthrove_user_fav_count": len(favoritePosts), + }).Trace("database: got all anthrove user favorites") + + return &graphModels.FavoriteList{Posts: favoritePosts}, nil +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 7395bdf..a13f15d 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -122,8 +122,7 @@ func (p *postgresqlConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]mod } func (p *postgresqlConnection) GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*graphModels.FavoriteList, error) { - //TODO implement me - panic("implement me") + return postgres.GetUserFavoriteNodeWithPagination(ctx, p.db, anthroveUserID, skip, limit) } func (p *postgresqlConnection) GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]graphModels.TagsWithFrequency, error) { -- 2.45.1 From 1da21024d74e6c62b64a32f6d8c0e33cfb0a3b45 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 15:16:31 +0200 Subject: [PATCH 034/124] feat(postgres): added GetUserTagsTroughFavedPosts --- internal/postgres/user.go | 44 +++++++++++++++++++++++++++++++++++++++ pkg/database/postgres.go | 3 +-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 676bfa4..f15b077 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -272,3 +272,47 @@ func GetUserFavoriteNodeWithPagination(ctx context.Context, db *gorm.DB, anthrov return &graphModels.FavoriteList{Posts: favoritePosts}, nil } + +func GetUserTagNodeWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) ([]graphModels.TagsWithFrequency, error) { + var userFavorites []pgModels.UserFavorite + err := db.WithContext(ctx).Where("user_id = ?", string(anthroveUserID)).Find(&userFavorites).Error + if err != nil { + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + }).Error("database: failed to get user favorites") + return nil, err + } + + tagFrequency := make(map[string]int) + for _, userFavorite := range userFavorites { + var postTags []pgModels.Tag + err = db.WithContext(ctx).Model(&pgModels.Post{}).Where("id = ?", userFavorite.PostID).Association("Tags").Find(&postTags) + if err != nil { + log.WithFields(log.Fields{ + "post_id": userFavorite.PostID, + }).Error("database: failed to get post tags") + return nil, err + } + + for _, tag := range postTags { + tagFrequency[tag.Name]++ + } + } + + var tagsWithFrequency []graphModels.TagsWithFrequency + for tagName, frequency := range tagFrequency { + tagsWithFrequency = append(tagsWithFrequency, graphModels.TagsWithFrequency{ + Frequency: int64(frequency), + Tags: graphModels.AnthroveTag{ + Name: tagName, + }, + }) + } + + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + "tag_amount": len(tagsWithFrequency), + }).Trace("database: got user tag node with relation to faved posts") + + return tagsWithFrequency, nil +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index a13f15d..c283bea 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -126,8 +126,7 @@ func (p *postgresqlConnection) GetUserFavoritePostsWithPagination(ctx context.Co } func (p *postgresqlConnection) GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]graphModels.TagsWithFrequency, error) { - //TODO implement me - panic("implement me") + return postgres.GetUserTagNodeWitRelationToFavedPosts(ctx, p.db, anthroveUserID) } func (p *postgresqlConnection) GetAllTags(ctx context.Context) ([]graphModels.TagsWithFrequency, error) { -- 2.45.1 From 5a242c69898abe72db784148126c580b87233c1e Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 14 Jun 2024 15:43:40 +0200 Subject: [PATCH 035/124] docs(postgres): updated readme --- README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 732fd42..ffd7f3f 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,19 @@ import ( ) func main() { - client := graph.NewGraphConnection() - err := client.Connect(context.Background(), "your-endpoint", "your-username", "your-password") + var err error + dbDebug := false + ctx := context.Background() + + pgClient := database.NewPostgresqlConnection(dbDebug) + err = pgClient.Connect(ctx, "your-endpoint", "your-username", "your-password", "anthrove", 5432, "disable", "Europe/Berlin") + if err != nil { + fmt.Println(err) + return + } + + graphClient := database.NewGraphConnection(dbDebug) + err = graphClient.Connect(ctx, "your-endpoint", "your-username", "your-password", "NOT USED",0,"NOT USED","NOT USED") if err != nil { fmt.Println(err) return -- 2.45.1 From 03ce8b52ae8c8e6e73fbdece6205571ec9519e3d Mon Sep 17 00:00:00 2001 From: soxx Date: Wed, 19 Jun 2024 23:32:42 +0200 Subject: [PATCH 036/124] test(postgres): added first tests and already fixed bugs --- go.mod | 57 ++++- go.sum | 178 ++++++++++++++- internal/postgres/post.go | 6 + internal/postgres/post_test.go | 136 ++++++++++++ internal/postgres/relationships.go | 19 +- internal/postgres/relationships_test.go | 280 ++++++++++++++++++++++++ internal/postgres/tag.go | 2 +- internal/postgres/user.go | 19 ++ pkg/models/const.go | 6 +- pkg/models/pgModels/postReference.go | 4 + pkg/models/pgModels/user.go | 4 + pkg/models/pgModels/userFavorite.go | 4 + test/helper.go | 77 +++++++ test/tag_test.go | 104 +++++++++ 14 files changed, 875 insertions(+), 21 deletions(-) create mode 100644 internal/postgres/post_test.go create mode 100644 internal/postgres/relationships_test.go create mode 100644 test/helper.go create mode 100644 test/tag_test.go diff --git a/go.mod b/go.mod index 4b598af..a25e991 100644 --- a/go.mod +++ b/go.mod @@ -4,25 +4,76 @@ go 1.22.0 require ( github.com/brianvoe/gofakeit/v7 v7.0.3 - github.com/lib/pq v1.10.7 + github.com/lib/pq v1.10.9 github.com/matoous/go-nanoid/v2 v2.1.0 github.com/neo4j/neo4j-go-driver/v5 v5.17.0 github.com/rubenv/sql-migrate v1.6.1 github.com/sirupsen/logrus v1.9.3 + github.com/stretchr/testify v1.9.0 + github.com/testcontainers/testcontainers-go v0.31.0 + github.com/testcontainers/testcontainers-go/modules/postgres v0.31.0 gorm.io/driver/postgres v1.5.7 gorm.io/gorm v1.25.10 ) require ( + dario.cat/mergo v1.0.0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/hcsshim v0.11.4 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/containerd/containerd v1.7.15 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/cpuguy83/dockercfg v0.3.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/distribution/reference v0.5.0 // indirect + github.com/docker/docker v25.0.5+incompatible // indirect + github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/pgx/v5 v5.5.5 // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - golang.org/x/crypto v0.21.0 // indirect + github.com/klauspost/compress v1.16.0 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/moby/patternmatcher v0.6.0 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/sys/user v0.1.0 // indirect + github.com/moby/term v0.5.0 // indirect + github.com/morikuni/aec v1.0.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/shirou/gopsutil/v3 v3.23.12 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect + golang.org/x/crypto v0.22.0 // indirect + golang.org/x/mod v0.16.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.18.0 // indirect + golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.13.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d // indirect + google.golang.org/grpc v1.58.3 // indirect + google.golang.org/protobuf v1.33.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 9cd0cd1..3b9b10a 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,61 @@ +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= +github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= github.com/brianvoe/gofakeit/v7 v7.0.3 h1:tGCt+eYfhTMWE1ko5G2EO1f/yE44yNpIwUb4h32O0wo= github.com/brianvoe/gofakeit/v7 v7.0.3/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/containerd/containerd v1.7.15 h1:afEHXdil9iAm03BmhjzKyXnnEBtjaLJefdU7DV0IFes= +github.com/containerd/containerd v1.7.15/go.mod h1:ISzRRTMF8EXNpJlTzyr2XMhN+j9K302C21/+cr3kUnY= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= +github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= +github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/docker v25.0.5+incompatible h1:UmQydMduGkrD5nQde1mecF/YnSbTOaPeFIeP5C4W+DE= +github.com/docker/docker v25.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs= github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= @@ -19,42 +68,157 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= -github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/matoous/go-nanoid/v2 v2.1.0 h1:P64+dmq21hhWdtvZfEAofnvJULaRR1Yib0+PnU669bE= github.com/matoous/go-nanoid/v2 v2.1.0/go.mod h1:KlbGNQ+FhrUNIHUxZdL63t7tl4LaPkZNpUULS8H4uVM= github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= +github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= +github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg= +github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/neo4j/neo4j-go-driver/v5 v5.17.0 h1:Bdqg1Y8Hd3uLYToXtBjysDYXTdMiP7zeUNUEwfbJkSo= github.com/neo4j/neo4j-go-driver/v5 v5.17.0/go.mod h1:Vff8OwT7QpLm7L2yYr85XNWe9Rbqlbeb9asNXJTHO4k= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rubenv/sql-migrate v1.6.1 h1:bo6/sjsan9HaXAsNxYP/jCEDUGibHp8JmOBw7NTGRos= github.com/rubenv/sql-migrate v1.6.1/go.mod h1:tPzespupJS0jacLfhbwto/UjSX+8h2FdWB7ar+QlHa0= +github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4= +github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +github.com/testcontainers/testcontainers-go v0.31.0 h1:W0VwIhcEVhRflwL9as3dhY6jXjVCA27AkmbnZ+UTh3U= +github.com/testcontainers/testcontainers-go v0.31.0/go.mod h1:D2lAoA0zUFiSY+eAflqK5mcUx/A5hrrORaEQrd0SefI= +github.com/testcontainers/testcontainers-go/modules/postgres v0.31.0 h1:isAwFS3KNKRbJMbWv+wolWqOFUECmjYZ+sIRZCIBc/E= +github.com/testcontainers/testcontainers-go/modules/postgres v0.31.0/go.mod h1:ZNYY8vumNCEG9YI59A9d6/YaMY49uwRhmeU563EzFGw= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= +go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= +golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 h1:Z0hjGZePRE0ZBWotvtrwxFNrNE9CUAGtplaDK5NNI/g= +google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw= +google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d h1:pgIUhmqwKOUlnKna4r6amKdUngdL8DrkpFeV8+VBElY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -65,3 +229,5 @@ gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM= gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA= gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= diff --git a/internal/postgres/post.go b/internal/postgres/post.go index 02ac938..1cd4472 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -2,6 +2,7 @@ package postgres import ( "context" + "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" log "github.com/sirupsen/logrus" @@ -30,6 +31,10 @@ func CreateAnthrovePostNode(ctx context.Context, db *gorm.DB, anthrovePostID mod } func CheckIfAnthrovePostNodeExistsByAnthroveID(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID) (bool, error) { + if anthrovePostID == "" { + return false, fmt.Errorf("anthrovePostID is required") + } + return executeCheckQuery(ctx, db, "id = ?", string(anthrovePostID)) } @@ -43,6 +48,7 @@ func CheckIfAnthrovePostNodeExistsBySourceID(ctx context.Context, db *gorm.DB, s func executeCheckQuery(ctx context.Context, db *gorm.DB, query string, args ...interface{}) (bool, error) { var count int64 + err := db.WithContext(ctx).Model(&pgModels.Post{}).Where(query, args...).Count(&count).Error if err != nil { return false, err diff --git a/internal/postgres/post_test.go b/internal/postgres/post_test.go new file mode 100644 index 0000000..20444e7 --- /dev/null +++ b/internal/postgres/post_test.go @@ -0,0 +1,136 @@ +package postgres + +import ( + "context" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/test" + _ "github.com/lib/pq" + "gorm.io/gorm" + "testing" +) + +func TestCreateAnthrovePostNode(t *testing.T) { + + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + type args struct { + ctx context.Context + db *gorm.DB + anthrovePostID models.AnthrovePostID + anthroveRating models.Rating + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid AnthrovePostID and Rating", + args: args{ + ctx: context.Background(), + db: gormDB, + anthrovePostID: "1234", + anthroveRating: models.Rating("safe"), + }, + wantErr: false, + }, + { + name: "Test 2: Invalid AnthrovePostID and Rating", + args: args{ + ctx: context.Background(), + db: gormDB, + anthrovePostID: "", + anthroveRating: "a4dsa4d", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := CreateAnthrovePostNode(tt.args.ctx, tt.args.db, tt.args.anthrovePostID, tt.args.anthroveRating); (err != nil) != tt.wantErr { + t.Errorf("CreateAnthrovePostNode() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestCheckIfAnthrovePostNodeExistsByAnthroveID(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + err = CreateAnthrovePostNode(ctx, gormDB, "1234", "safe") + if err != nil { + t.Fatal(err) + } + + // Test + + type args struct { + ctx context.Context + db *gorm.DB + anthrovePostID models.AnthrovePostID + } + tests := []struct { + name string + args args + want bool + wantErr bool + }{ + { + name: "Test 1: Valid AnthroveID", + args: args{ + ctx: ctx, + db: gormDB, + anthrovePostID: "1234", + }, + want: true, + wantErr: false, + }, + { + name: "Test 2: Invalid AnthroveID", + args: args{ + ctx: ctx, + db: gormDB, + anthrovePostID: "123456", + }, + want: false, + wantErr: false, + }, + { + name: "Test 3: No AnthroveID", + args: args{ + ctx: ctx, + db: gormDB, + anthrovePostID: "", + }, + want: false, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := CheckIfAnthrovePostNodeExistsByAnthroveID(tt.args.ctx, tt.args.db, tt.args.anthrovePostID) + if (err != nil) != tt.wantErr { + t.Errorf("CheckIfAnthrovePostNodeExistsByAnthroveID() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("CheckIfAnthrovePostNodeExistsByAnthroveID() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index fd855eb..7ee9fd7 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -2,6 +2,7 @@ package postgres import ( "context" + "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" log "github.com/sirupsen/logrus" @@ -9,14 +10,8 @@ import ( ) func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string) error { - var post pgModels.Post var source pgModels.Source - - // Find the post - err := db.WithContext(ctx).Where("id = ?", anthrovePostID).First(&post).Error - if err != nil { - return err - } + var err error // Find the source err = db.WithContext(ctx).Where("domain = ?", anthroveSourceDomain).First(&source).Error @@ -25,7 +20,11 @@ func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrov } // Establish the relationship - err = db.WithContext(ctx).Model(&post).Association("Sources").Append(&source) + err = db.WithContext(ctx).Create(pgModels.PostReference{ + PostID: string(anthrovePostID), + SourceID: source.ID, + }).Error + if err != nil { return err } @@ -66,6 +65,10 @@ func CheckUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID models exists := count > 0 + if !exists { + return false, fmt.Errorf("no post link exists") + } + log.WithFields(log.Fields{ "relationship_exists": exists, "relationship_anthrove_user_id": anthroveUserID, diff --git a/internal/postgres/relationships_test.go b/internal/postgres/relationships_test.go new file mode 100644 index 0000000..d5033d9 --- /dev/null +++ b/internal/postgres/relationships_test.go @@ -0,0 +1,280 @@ +package postgres + +import ( + "context" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" + "git.dragse.it/anthrove/otter-space-sdk/test" + "gorm.io/gorm" + "testing" +) + +func TestEstablishAnthrovePostToSourceLink(t *testing.T) { + + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + err = CreateAnthrovePostNode(ctx, gormDB, "1234", "safe") + if err != nil { + t.Fatal(err) + } + + source := &pgModels.Source{ + DisplayName: "e621", + Domain: "e621.net", + Icon: "icon.e621.net", + } + err = CreateSourceNode(ctx, gormDB, source) + if err != nil { + t.Fatal(err) + } + + // Test + + type args struct { + ctx context.Context + db *gorm.DB + anthrovePostID models.AnthrovePostID + anthroveSourceDomain string + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid AnthrovePostID and anthroveSourceDomain", + args: args{ + ctx: ctx, + db: gormDB, + anthrovePostID: "1234", + anthroveSourceDomain: "e621.net", + }, + wantErr: false, + }, + { + name: "Test 2: Invalid AnthrovePostID and Valid anthroveSourceDomain", + args: args{ + ctx: ctx, + db: gormDB, + anthrovePostID: "123456", + anthroveSourceDomain: "e621.net", + }, + wantErr: true, + }, + { + name: "Test 3: Invalid anthroveSourceDomain and Valid AnthrovePostID", + args: args{ + ctx: ctx, + db: gormDB, + anthrovePostID: "1234", + anthroveSourceDomain: "fa.banana", + }, + wantErr: true, + }, + { + name: "Test 4: Invalid anthroveSourceDomain and Invalid AnthrovePostID", + args: args{ + ctx: ctx, + db: gormDB, + anthrovePostID: "696969", + anthroveSourceDomain: "hehe.funny.number", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := EstablishAnthrovePostToSourceLink(tt.args.ctx, tt.args.db, tt.args.anthrovePostID, tt.args.anthroveSourceDomain); (err != nil) != tt.wantErr { + t.Errorf("EstablishAnthrovePostToSourceLink() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestEstablishUserToPostLink(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + err = CreateUser(ctx, gormDB, "1") + if err != nil { + t.Fatal(err) + } + + err = CreateAnthrovePostNode(ctx, gormDB, "1234", "safe") + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + anthroveUserID models.AnthroveUserID + anthrovePostID models.AnthrovePostID + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid AnthroveUserID and AnthrovePostID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + anthrovePostID: "1234", + }, + wantErr: false, + }, + { + name: "Test 2: Valid AnthroveUserID and invalid AnthrovePostID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + anthrovePostID: "123456", + }, + wantErr: true, + }, + { + name: "Test 3: Valid AnthrovePostID and invalid AnthroveUserID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "123", + anthrovePostID: "1234", + }, + wantErr: true, + }, + { + name: "Test 4: Invalid AnthrovePostID and invalid AnthroveUserID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "123", + anthrovePostID: "123456", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := EstablishUserToPostLink(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.anthrovePostID); (err != nil) != tt.wantErr { + t.Errorf("EstablishUserToPostLink() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestCheckUserToPostLink(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + err = CreateUser(ctx, gormDB, "1") + if err != nil { + t.Fatal(err) + } + + err = CreateAnthrovePostNode(ctx, gormDB, "1234", "safe") + if err != nil { + t.Fatal(err) + } + + err = EstablishUserToPostLink(ctx, gormDB, "1", "1234") + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + anthroveUserID models.AnthroveUserID + anthrovePostID models.AnthrovePostID + } + tests := []struct { + name string + args args + want bool + wantErr bool + }{ + { + name: "Test 1: Valid AnthroveUserID and AnthrovePostID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + anthrovePostID: "1234", + }, + want: true, + wantErr: false, + }, + { + name: "Test 2: Valid AnthroveUserID and invalid AnthrovePostID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + anthrovePostID: "123456", + }, + want: false, + wantErr: true, + }, + { + name: "Test 3: Valid AnthrovePostID and invalid AnthroveUserID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "123", + anthrovePostID: "1234", + }, + want: false, + wantErr: true, + }, + { + name: "Test 4: Invalid AnthrovePostID and invalid AnthroveUserID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "123", + anthrovePostID: "123456", + }, + want: false, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := CheckUserToPostLink(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.anthrovePostID) + if (err != nil) != tt.wantErr { + t.Errorf("CheckUserToPostLink() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("CheckUserToPostLink() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index d873506..02072c2 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -22,7 +22,7 @@ func CreateTagNodeWitRelation(ctx context.Context, db *gorm.DB, PostID models.An }, } - err := db.WithContext(ctx).Model(pgPost).Association("Tags").Append(tag) + err := db.WithContext(ctx).Model(&pgPost).Association("Tags").Append(tag) if err != nil { return err diff --git a/internal/postgres/user.go b/internal/postgres/user.go index f15b077..472625a 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -9,6 +9,25 @@ import ( "gorm.io/gorm" ) +func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) error { + + user := pgModels.User{ + BaseModel: pgModels.BaseModel{ + ID: string(anthroveUserID), + }, + } + + err := db.WithContext(ctx).Create(&user).Error + if err != nil { + log.WithFields(log.Fields{ + "anthrove_user_id": anthroveUserID, + }).Error("database: failed to create user") + return err + } + + return nil +} + func CreateUserNodeWithSourceRelation(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error { user := pgModels.User{ BaseModel: pgModels.BaseModel{ diff --git a/pkg/models/const.go b/pkg/models/const.go index 552193d..0b7d944 100644 --- a/pkg/models/const.go +++ b/pkg/models/const.go @@ -6,9 +6,9 @@ type Rating string type TagType string const ( - SFW Rating = "s" - NSFW Rating = "e" - Questionable Rating = "q" + SFW Rating = "safe" + NSFW Rating = "explicit" + Questionable Rating = "questionable" Unknown Rating = "unknown" ) diff --git a/pkg/models/pgModels/postReference.go b/pkg/models/pgModels/postReference.go index 1163731..8ab7797 100644 --- a/pkg/models/pgModels/postReference.go +++ b/pkg/models/pgModels/postReference.go @@ -9,3 +9,7 @@ type PostReference struct { PreviewFileURL string SampleFileURL string } + +func (PostReference) TableName() string { + return "PostReference" +} diff --git a/pkg/models/pgModels/user.go b/pkg/models/pgModels/user.go index 7fe7e73..1120ae7 100644 --- a/pkg/models/pgModels/user.go +++ b/pkg/models/pgModels/user.go @@ -6,3 +6,7 @@ type User struct { Favorites []UserFavorite `gorm:"foreignKey:UserID"` Sources []UserSource `gorm:"foreignKey:UserID"` } + +func (User) TableName() string { + return "User" +} diff --git a/pkg/models/pgModels/userFavorite.go b/pkg/models/pgModels/userFavorite.go index 2e194a3..e01093f 100644 --- a/pkg/models/pgModels/userFavorite.go +++ b/pkg/models/pgModels/userFavorite.go @@ -7,3 +7,7 @@ type UserFavorite struct { PostID string `gorm:"primaryKey"` CreatedAt time.Time } + +func (UserFavorite) TableName() string { + return "UserFavorites" +} diff --git a/test/helper.go b/test/helper.go new file mode 100644 index 0000000..4f50991 --- /dev/null +++ b/test/helper.go @@ -0,0 +1,77 @@ +package test + +import ( + "context" + "database/sql" + migrate "github.com/rubenv/sql-migrate" + postgrescontainer "github.com/testcontainers/testcontainers-go/modules/postgres" + "gorm.io/driver/postgres" + "gorm.io/gorm" + "time" + + "github.com/testcontainers/testcontainers-go" + "github.com/testcontainers/testcontainers-go/wait" +) + +const ( + databaseName = "anthrove" + databaseUser = "anthrove" + databasePassword = "anthrove" + migrationSource = "../../pkg/database/migrations" +) + +func StartPostgresContainer(ctx context.Context) (*postgrescontainer.PostgresContainer, *gorm.DB, error) { + + pgContainer, err := postgrescontainer.RunContainer(ctx, + testcontainers.WithImage("postgres:alpine"), + postgrescontainer.WithDatabase(databaseName), + postgrescontainer.WithUsername(databaseUser), + postgrescontainer.WithPassword(databasePassword), + testcontainers.WithWaitStrategy( + wait.ForLog("database system is ready to accept connections"). + WithOccurrence(2).WithStartupTimeout(5*time.Second)), + ) + if err != nil { + return nil, nil, err + } + + connectionString, err := pgContainer.ConnectionString(ctx, "sslmode=disable") + if err != nil { + return nil, nil, err + } + + err = migrateDatabase(connectionString) + if err != nil { + return nil, nil, err + + } + + gormDB, err := getGormDB(connectionString) + if err != nil { + return nil, nil, err + } + return pgContainer, gormDB, nil +} + +func migrateDatabase(connectionString string) error { + db, err := sql.Open("postgres", connectionString) + if err != nil { + return err + } + + migrations := &migrate.FileMigrationSource{ + Dir: migrationSource, + } + + _, err = migrate.Exec(db, "postgres", migrations, migrate.Up) + if err != nil { + return err + } + + return nil + +} + +func getGormDB(connectionString string) (*gorm.DB, error) { + return gorm.Open(postgres.Open(connectionString), &gorm.Config{}) +} diff --git a/test/tag_test.go b/test/tag_test.go new file mode 100644 index 0000000..3c9c4f8 --- /dev/null +++ b/test/tag_test.go @@ -0,0 +1,104 @@ +package test + +import ( + "context" + "git.dragse.it/anthrove/otter-space-sdk/pkg/database" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" + "log" + "strconv" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" +) + +type CustomerRepoTestSuite struct { + suite.Suite + database database.OtterSpace + pgContainer *PostgresContainer + ctx context.Context +} + +func (suite *CustomerRepoTestSuite) SetupSuite() { + suite.ctx = context.Background() + pgContainer, err := CreatePostgresContainer(suite.ctx) + if err != nil { + log.Fatal(err) + } + suite.pgContainer = pgContainer + + databaseClient := database.NewPostgresqlConnection(true) + containerInspect, _ := suite.pgContainer.Inspect(suite.ctx) + dbPortMap := containerInspect.NetworkSettings.Ports + var dbPortStr string + for _, v := range dbPortMap { + for _, n := range v { + dbPortStr = n.HostPort + } + } + dbPort, err := strconv.Atoi(dbPortStr) + if err != nil { + log.Fatal(err) + } + err = databaseClient.Connect(suite.ctx, "localhost", suite.pgContainer.DatabaseUser, suite.pgContainer.DatabasePassword, suite.pgContainer.DatabaseName, dbPort, "disable", "Europe/Berlin") + if err != nil { + log.Fatal(err) + } + suite.database = databaseClient + +} + +func (suite *CustomerRepoTestSuite) TearDownSuite() { + if err := suite.pgContainer.Terminate(suite.ctx); err != nil { + log.Fatalf("error terminating postgres container: %s", err) + } +} + +func (suite *CustomerRepoTestSuite) TestCreateTagNodeWitRelation() { + t := suite.T() + post := graphModels.AnthrovePost{ + PostID: "1234", + Rating: models.SFW, + } + + tag := &graphModels.AnthroveTag{ + Name: "test_tag", + Type: "general", + } + + err := suite.database.AddPost(suite.ctx, &post) + + if err != nil { + t.Fatal(err) + } + + err = suite.database.AddTagWithRelationToPost(suite.ctx, "1234", tag) + + assert.NoError(t, err) +} + +func (suite *CustomerRepoTestSuite) TestGetTags() { + t := suite.T() + + expectedTag := []graphModels.TagsWithFrequency{ + { + Frequency: 0, + Tags: graphModels.AnthroveTag{ + Name: "test_tag", + Type: "general", + }, + }, + } + + tag, err := suite.database.GetAllTags(suite.ctx) + + assert.NoError(t, err) + assert.Equal(t, expectedTag, tag) + assert.Len(t, tag, 1) + +} + +func TestCustomerRepoTestSuite(t *testing.T) { + suite.Run(t, new(CustomerRepoTestSuite)) +} -- 2.45.1 From e7cf655362fb56491ee60fb049f4b5432af142f8 Mon Sep 17 00:00:00 2001 From: soxx Date: Thu, 20 Jun 2024 00:13:39 +0200 Subject: [PATCH 037/124] test(postgres): added sources and fixed bugs --- internal/postgres/source.go | 12 +- internal/postgres/source_test.go | 259 +++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+), 2 deletions(-) create mode 100644 internal/postgres/source_test.go diff --git a/internal/postgres/source.go b/internal/postgres/source.go index 3d2cdca..1b013da 100644 --- a/internal/postgres/source.go +++ b/internal/postgres/source.go @@ -2,6 +2,7 @@ package postgres import ( "context" + "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" log "github.com/sirupsen/logrus" @@ -11,6 +12,10 @@ import ( // CreateSourceNode creates a pgModels.Source func CreateSourceNode(ctx context.Context, db *gorm.DB, anthroveSource *pgModels.Source) error { + if anthroveSource.Domain == "" { + return fmt.Errorf("anthroveSource domain is required") + } + result := db.WithContext(ctx).Create(anthroveSource) if result.Error != nil { @@ -45,8 +50,11 @@ func GetAllSourceNodes(ctx context.Context, db *gorm.DB) ([]pgModels.Source, err // GetSourceNodesByURL returns the first source it finds based on the domain func GetSourceNodesByURL(ctx context.Context, db *gorm.DB, domain string) (*pgModels.Source, error) { + var sources pgModels.Source - var sources *pgModels.Source + if domain == "" { + return nil, fmt.Errorf("domain is required") + } result := db.WithContext(ctx).Where("domain = ?", domain).First(&sources) @@ -58,5 +66,5 @@ func GetSourceNodesByURL(ctx context.Context, db *gorm.DB, domain string) (*pgMo "tag_amount": result.RowsAffected, }).Trace("database: get all source nodes") - return sources, nil + return &sources, nil } diff --git a/internal/postgres/source_test.go b/internal/postgres/source_test.go new file mode 100644 index 0000000..2bde71b --- /dev/null +++ b/internal/postgres/source_test.go @@ -0,0 +1,259 @@ +package postgres + +import ( + "context" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" + "git.dragse.it/anthrove/otter-space-sdk/test" + "gorm.io/gorm" + "testing" +) + +func TestCreateSourceNode(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validAnthroveSource := &pgModels.Source{ + DisplayName: "e621", + Domain: "e621.net", + Icon: "icon.e621.net", + } + + invalidAnthroveSource := &pgModels.Source{ + Domain: "", + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + anthroveSource *pgModels.Source + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid anthroveSource", + args: args{ + ctx: ctx, + db: gormDB, + anthroveSource: validAnthroveSource, + }, + wantErr: false, + }, + { + name: "Test 2: inValid anthroveSource", + args: args{ + ctx: ctx, + db: gormDB, + anthroveSource: invalidAnthroveSource, + }, + wantErr: true, + }, + { + name: "Test 3: unique anthroveSource", + args: args{ + ctx: ctx, + db: gormDB, + anthroveSource: validAnthroveSource, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := CreateSourceNode(tt.args.ctx, tt.args.db, tt.args.anthroveSource); (err != nil) != tt.wantErr { + t.Errorf("CreateSourceNode() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestGetAllSourceNodes(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + sources := []pgModels.Source{ + { + DisplayName: "e621", + Domain: "e621.net", + Icon: "icon.e621.net", + }, + { + DisplayName: "furaffinity", + Domain: "furaffinity.net", + Icon: "icon.furaffinity.net", + }, + { + DisplayName: "fenpaws", + Domain: "fenpa.ws", + Icon: "icon.fenpa.ws", + }, + } + + for _, source := range sources { + err = CreateSourceNode(ctx, gormDB, &source) + if err != nil { + t.Fatal(err) + } + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + } + tests := []struct { + name string + args args + want []pgModels.Source + wantErr bool + }{ + { + name: "Test 1: Get all entries", + args: args{ + ctx: ctx, + db: gormDB, + }, + want: sources, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetAllSourceNodes(tt.args.ctx, tt.args.db) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllSourceNodes() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !checkSourcesNode(got, tt.want) { + t.Errorf("GetAllSourceNodes() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGetSourceNodesByURL(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + source := &pgModels.Source{ + DisplayName: "e621", + Domain: "e621.net", + Icon: "icon.e621.net", + } + + err = CreateSourceNode(ctx, gormDB, source) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + domain string + } + tests := []struct { + name string + args args + want *pgModels.Source + wantErr bool + }{ + { + name: "Test 1: Valid URL", + args: args{ + ctx: ctx, + db: gormDB, + domain: "e621.net", + }, + want: source, + wantErr: false, + }, + { + name: "Test 2: Invalid URL", + args: args{ + ctx: ctx, + db: gormDB, + domain: "eeeee.net", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 2: No URL", + args: args{ + ctx: ctx, + db: gormDB, + domain: "", + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetSourceNodesByURL(tt.args.ctx, tt.args.db, tt.args.domain) + if (err != nil) != tt.wantErr { + t.Errorf("GetSourceNodesByURL() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !checkSourceNode(got, tt.want) { + t.Errorf("GetSourceNodesByURL() got = %v, want %v", got, tt.want) + } + }) + } +} + +func checkSourcesNode(got []pgModels.Source, want []pgModels.Source) bool { + for i, source := range want { + if source.DisplayName != got[i].DisplayName { + return false + } + if source.Domain != got[i].Domain { + return false + } + if source.Icon != got[i].Icon { + return false + } + } + + return true + +} + +func checkSourceNode(got *pgModels.Source, want *pgModels.Source) bool { + + if want == nil && got == nil { + return true + } + + if got.Domain != want.Domain { + return false + } + + return true + +} -- 2.45.1 From e6931570c3b98ec2f354b73e0cdd7bc68f07c6a2 Mon Sep 17 00:00:00 2001 From: SoXX Date: Wed, 19 Jun 2024 22:16:42 +0000 Subject: [PATCH 038/124] chore(postgres): removed dead code --- test/tag_test.go | 104 ----------------------------------------------- 1 file changed, 104 deletions(-) delete mode 100644 test/tag_test.go diff --git a/test/tag_test.go b/test/tag_test.go deleted file mode 100644 index 3c9c4f8..0000000 --- a/test/tag_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package test - -import ( - "context" - "git.dragse.it/anthrove/otter-space-sdk/pkg/database" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" - "log" - "strconv" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" -) - -type CustomerRepoTestSuite struct { - suite.Suite - database database.OtterSpace - pgContainer *PostgresContainer - ctx context.Context -} - -func (suite *CustomerRepoTestSuite) SetupSuite() { - suite.ctx = context.Background() - pgContainer, err := CreatePostgresContainer(suite.ctx) - if err != nil { - log.Fatal(err) - } - suite.pgContainer = pgContainer - - databaseClient := database.NewPostgresqlConnection(true) - containerInspect, _ := suite.pgContainer.Inspect(suite.ctx) - dbPortMap := containerInspect.NetworkSettings.Ports - var dbPortStr string - for _, v := range dbPortMap { - for _, n := range v { - dbPortStr = n.HostPort - } - } - dbPort, err := strconv.Atoi(dbPortStr) - if err != nil { - log.Fatal(err) - } - err = databaseClient.Connect(suite.ctx, "localhost", suite.pgContainer.DatabaseUser, suite.pgContainer.DatabasePassword, suite.pgContainer.DatabaseName, dbPort, "disable", "Europe/Berlin") - if err != nil { - log.Fatal(err) - } - suite.database = databaseClient - -} - -func (suite *CustomerRepoTestSuite) TearDownSuite() { - if err := suite.pgContainer.Terminate(suite.ctx); err != nil { - log.Fatalf("error terminating postgres container: %s", err) - } -} - -func (suite *CustomerRepoTestSuite) TestCreateTagNodeWitRelation() { - t := suite.T() - post := graphModels.AnthrovePost{ - PostID: "1234", - Rating: models.SFW, - } - - tag := &graphModels.AnthroveTag{ - Name: "test_tag", - Type: "general", - } - - err := suite.database.AddPost(suite.ctx, &post) - - if err != nil { - t.Fatal(err) - } - - err = suite.database.AddTagWithRelationToPost(suite.ctx, "1234", tag) - - assert.NoError(t, err) -} - -func (suite *CustomerRepoTestSuite) TestGetTags() { - t := suite.T() - - expectedTag := []graphModels.TagsWithFrequency{ - { - Frequency: 0, - Tags: graphModels.AnthroveTag{ - Name: "test_tag", - Type: "general", - }, - }, - } - - tag, err := suite.database.GetAllTags(suite.ctx) - - assert.NoError(t, err) - assert.Equal(t, expectedTag, tag) - assert.Len(t, tag, 1) - -} - -func TestCustomerRepoTestSuite(t *testing.T) { - suite.Run(t, new(CustomerRepoTestSuite)) -} -- 2.45.1 From 83a5c894384d718c1b10905c4b8eae41b9ae976d Mon Sep 17 00:00:00 2001 From: SoXX Date: Thu, 20 Jun 2024 14:54:06 +0200 Subject: [PATCH 039/124] test(postgres): added tag and fixed bugs Signed-off-by: soxx --- internal/postgres/tag.go | 21 ++++ internal/postgres/tag_test.go | 175 ++++++++++++++++++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 internal/postgres/tag_test.go diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 02072c2..4249069 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -2,14 +2,35 @@ package postgres import ( "context" + "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) +func CreateTag(ctx context.Context, db *gorm.DB, tag *pgModels.Tag) error { + + resultTag := db.WithContext(ctx).Where(tag).Create(tag) + + if resultTag.Error != nil { + return resultTag.Error + } + + log.WithFields(log.Fields{ + "tag_name": tag.Name, + "tag_type": tag.Type, + }).Trace("database: created tag node") + + return nil +} + func CreateTagNodeWitRelation(ctx context.Context, db *gorm.DB, PostID models.AnthrovePostID, tag *pgModels.Tag) error { + if PostID == "" { + return fmt.Errorf("PostID is empty") + } + resultTag := db.WithContext(ctx).Where(tag).FirstOrCreate(tag) if resultTag.Error != nil { diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go new file mode 100644 index 0000000..347754e --- /dev/null +++ b/internal/postgres/tag_test.go @@ -0,0 +1,175 @@ +package postgres + +import ( + "context" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" + "git.dragse.it/anthrove/otter-space-sdk/test" + "gorm.io/gorm" + "testing" +) + +func TestCreateTagNodeWitRelation(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + err = CreateAnthrovePostNode(ctx, gormDB, "1234", "safe") + if err != nil { + t.Fatal(err) + } + + tag := &pgModels.Tag{ + Name: "JayTheFerret", + Type: "artist", + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + PostID models.AnthrovePostID + tag *pgModels.Tag + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid PostID and Tag", + args: args{ + ctx: ctx, + db: gormDB, + PostID: "1234", + tag: tag, + }, + wantErr: false, + }, + { + name: "Test 2: Valid PostID and invalid Tag", + args: args{ + ctx: ctx, + db: gormDB, + PostID: "1234", + tag: nil, + }, + wantErr: true, + }, + { + name: "Test 3: Invalid PostID and valid Tag", + args: args{ + ctx: ctx, + db: gormDB, + PostID: "123456", + tag: tag, + }, + wantErr: true, + }, + { + name: "Test 4: No PostID and valid Tag", + args: args{ + ctx: ctx, + db: gormDB, + PostID: "", + tag: tag, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := CreateTagNodeWitRelation(tt.args.ctx, tt.args.db, tt.args.PostID, tt.args.tag); (err != nil) != tt.wantErr { + t.Errorf("CreateTagNodeWitRelation() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestGetTags(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + tags := []pgModels.Tag{ + { + Name: "JayTheFerret", + Type: "artist", + }, + { + Name: "anthro", + Type: "general", + }, + { + Name: "soxx", + Type: "character", + }, + } + + for _, tag := range tags { + err = CreateTag(ctx, gormDB, &tag) + if err != nil { + t.Fatal(err) + } + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + } + tests := []struct { + name string + args args + want []pgModels.Tag + wantErr bool + }{ + { + name: "Test 1: Get Tags", + args: args{ + ctx: ctx, + db: gormDB, + }, + want: tags, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetTags(tt.args.ctx, tt.args.db) + if (err != nil) != tt.wantErr { + t.Errorf("GetTags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !checkTag(got, tt.want) { + t.Errorf("GetTags() got = %v, want %v", got, tt.want) + } + }) + } +} + +func checkTag(got []pgModels.Tag, want []pgModels.Tag) bool { + for i, tag := range want { + if tag.Type != got[i].Type { + return false + } + if tag.Name != got[i].Name { + return false + } + } + + return true + +} -- 2.45.1 From 947a77d13fd6b6d1dbbfa6afa4f597c0ee1fd3b8 Mon Sep 17 00:00:00 2001 From: soxx Date: Thu, 20 Jun 2024 15:24:55 +0200 Subject: [PATCH 040/124] test(postgres): added first tests for user and fixed bugs Signed-off-by: soxx --- internal/postgres/user.go | 15 + internal/postgres/user_test.go | 453 ++++++++++++++++++++++++++++++ pkg/models/pgModels/userSource.go | 4 + 3 files changed, 472 insertions(+) create mode 100644 internal/postgres/user_test.go diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 472625a..5181cbe 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -2,6 +2,7 @@ package postgres import ( "context" + "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" @@ -11,6 +12,10 @@ import ( func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) error { + if anthroveUserID == "" { + return fmt.Errorf("anthroveUserID cannot be empty") + } + user := pgModels.User{ BaseModel: pgModels.BaseModel{ ID: string(anthroveUserID), @@ -29,6 +34,11 @@ func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Anthrove } func CreateUserNodeWithSourceRelation(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error { + + if anthroveUserID == "" || username == "" || userID == "" { + return fmt.Errorf("anthroveUserID cannot be empty") + } + user := pgModels.User{ BaseModel: pgModels.BaseModel{ ID: string(anthroveUserID), @@ -181,6 +191,11 @@ func GetSpecifiedUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID } func GetAnthroveUser(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) (*graphModels.AnthroveUser, error) { + + if anthroveUserID == "" { + return nil, fmt.Errorf("anthroveUserID cannot be empty") + } + var user pgModels.User var userSources []pgModels.UserSource anthroveUser := &graphModels.AnthroveUser{ diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go new file mode 100644 index 0000000..26f316f --- /dev/null +++ b/internal/postgres/user_test.go @@ -0,0 +1,453 @@ +package postgres + +import ( + "context" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" + "git.dragse.it/anthrove/otter-space-sdk/test" + "gorm.io/gorm" + "reflect" + "testing" +) + +func TestCreateUser(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + // Test + type args struct { + ctx context.Context + db *gorm.DB + anthroveUserID models.AnthroveUserID + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid AnthroveUserID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + }, + wantErr: false, + }, + { + name: "Test 2: Invalid AnthroveUserID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := CreateUser(tt.args.ctx, tt.args.db, tt.args.anthroveUserID); (err != nil) != tt.wantErr { + t.Errorf("CreateUser() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestCreateUserNodeWithSourceRelation(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + source := &pgModels.Source{ + DisplayName: "e621", + Domain: "e621.net", + Icon: "icon.e621.net", + } + err = CreateSourceNode(ctx, gormDB, source) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + anthroveUserID models.AnthroveUserID + sourceDomain string + userID string + username string + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid anthroveUserID, sourceDomain, userID, username", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + sourceDomain: "e621.net", + userID: "e1", + username: "marius", + }, + wantErr: false, + }, + { + name: "Test 2: Invalid anthroveUserID, valid sourceDomain, userID, username", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "2", + sourceDomain: "e621.net", + userID: "e1", + username: "marius", + }, + wantErr: true, + }, + { + name: "Test 3: Empty anthroveUserID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "", + sourceDomain: "e621.net", + userID: "e1", + username: "marius", + }, + wantErr: true, + }, + { + name: "Test 4: invalid sourceDomain", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + sourceDomain: "fa.net", + userID: "e1", + username: "marius", + }, + wantErr: true, + }, + { + name: "Test 5: no userID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + sourceDomain: "e621.net", + userID: "", + username: "marius", + }, + wantErr: true, + }, + { + name: "Test 6: no username", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + sourceDomain: "e621.net", + userID: "aa", + username: "", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := CreateUserNodeWithSourceRelation(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.sourceDomain, tt.args.userID, tt.args.username); (err != nil) != tt.wantErr { + t.Errorf("CreateUserNodeWithSourceRelation() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestGetAllAnthroveUserIDs(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + users := []models.AnthroveUserID{"1", "2", "3"} + + for _, user := range users { + err = CreateUser(ctx, gormDB, user) + if err != nil { + t.Fatal(err) + } + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + } + tests := []struct { + name string + args args + want []models.AnthroveUserID + wantErr bool + }{ + { + name: "Test 1: Get Data", + args: args{ + ctx: ctx, + db: gormDB, + }, + want: users, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetAllAnthroveUserIDs(tt.args.ctx, tt.args.db) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllAnthroveUserIDs() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetAllAnthroveUserIDs() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGetAnthroveUser(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + user := graphModels.AnthroveUser{ + UserID: "1", + } + err = CreateUser(ctx, gormDB, user.UserID) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + anthroveUserID models.AnthroveUserID + } + tests := []struct { + name string + args args + want *graphModels.AnthroveUser + wantErr bool + }{ + { + name: "Test 1: Valid AnthroveUserID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + }, + want: &user, + wantErr: false, + }, + { + name: "Test 2: Invalid AnthroveUserID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "2", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 3: No AnthroveUserID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "", + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetAnthroveUser(tt.args.ctx, tt.args.db, tt.args.anthroveUserID) + if (err != nil) != tt.wantErr { + t.Errorf("GetAnthroveUser() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetAnthroveUser() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGetSpecifiedUserSourceLink(t *testing.T) { + type args struct { + ctx context.Context + db *gorm.DB + anthroveUserID models.AnthroveUserID + sourceDisplayName string + } + tests := []struct { + name string + args args + want map[string]graphModels.AnthroveUserRelationship + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetSpecifiedUserSourceLink(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.sourceDisplayName) + if (err != nil) != tt.wantErr { + t.Errorf("GetSpecifiedUserSourceLink() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetSpecifiedUserSourceLink() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGetUserFavoriteNodeWithPagination(t *testing.T) { + type args struct { + ctx context.Context + db *gorm.DB + anthroveUserID models.AnthroveUserID + skip int + limit int + } + tests := []struct { + name string + args args + want *graphModels.FavoriteList + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetUserFavoriteNodeWithPagination(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.skip, tt.args.limit) + if (err != nil) != tt.wantErr { + t.Errorf("GetUserFavoriteNodeWithPagination() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetUserFavoriteNodeWithPagination() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGetUserFavoritesCount(t *testing.T) { + type args struct { + ctx context.Context + db *gorm.DB + anthroveUserID models.AnthroveUserID + } + tests := []struct { + name string + args args + want int64 + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetUserFavoritesCount(tt.args.ctx, tt.args.db, tt.args.anthroveUserID) + if (err != nil) != tt.wantErr { + t.Errorf("GetUserFavoritesCount() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("GetUserFavoritesCount() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGetUserSourceLink(t *testing.T) { + type args struct { + ctx context.Context + db *gorm.DB + anthroveUserID models.AnthroveUserID + } + tests := []struct { + name string + args args + want map[string]graphModels.AnthroveUserRelationship + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetUserSourceLink(tt.args.ctx, tt.args.db, tt.args.anthroveUserID) + if (err != nil) != tt.wantErr { + t.Errorf("GetUserSourceLink() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetUserSourceLink() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { + type args struct { + ctx context.Context + db *gorm.DB + anthroveUserID models.AnthroveUserID + } + tests := []struct { + name string + args args + want []graphModels.TagsWithFrequency + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetUserTagNodeWitRelationToFavedPosts(tt.args.ctx, tt.args.db, tt.args.anthroveUserID) + if (err != nil) != tt.wantErr { + t.Errorf("GetUserTagNodeWitRelationToFavedPosts() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetUserTagNodeWitRelationToFavedPosts() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/models/pgModels/userSource.go b/pkg/models/pgModels/userSource.go index 7319994..a87494f 100644 --- a/pkg/models/pgModels/userSource.go +++ b/pkg/models/pgModels/userSource.go @@ -6,3 +6,7 @@ type UserSource struct { AccountUsername string AccountID string } + +func (UserSource) TableName() string { + return "UserSource" +} -- 2.45.1 From 84aee5c2dda5d203ebf2eadfd4bf1ceb01d2de14 Mon Sep 17 00:00:00 2001 From: soxx Date: Thu, 20 Jun 2024 22:45:03 +0200 Subject: [PATCH 041/124] test(postgres): finished tests for user and fixed bugs Signed-off-by: soxx --- internal/postgres/user.go | 31 +- internal/postgres/user_test.go | 474 +++++++++++++++++- .../migrations/001_inital_database.sql | 10 +- pkg/models/pgModels/orm.go | 2 +- pkg/models/pgModels/userSource.go | 1 + test/helper.go | 5 +- 6 files changed, 502 insertions(+), 21 deletions(-) diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 5181cbe..921af51 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -91,6 +91,10 @@ func CreateUserNodeWithSourceRelation(ctx context.Context, db *gorm.DB, anthrove } func GetUserFavoritesCount(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) (int64, error) { + if anthroveUserID == "" { + return 0, fmt.Errorf("anthroveUserID cannot be empty") + } + var count int64 err := db.WithContext(ctx).Model(&pgModels.UserFavorite{}).Where("user_id = ?", string(anthroveUserID)).Count(&count).Error if err != nil { @@ -149,10 +153,14 @@ func GetUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID models.A } func GetSpecifiedUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]graphModels.AnthroveUserRelationship, error) { + if anthroveUserID == "" || sourceDisplayName == "" { + return nil, fmt.Errorf("anthroveUserID or sourceDisplayName is empty") + } + var userSources []pgModels.UserSource userSourceMap := make(map[string]graphModels.AnthroveUserRelationship) - err := db.WithContext(ctx).Model(&pgModels.UserSource{}).Joins("Source").Where("user_id = ? AND display_name = ?", string(anthroveUserID), sourceDisplayName).Find(&userSources).Error + err := db.WithContext(ctx).Model(&pgModels.UserSource{}).InnerJoins("Source", db.Where("display_name = ?", sourceDisplayName)).Where("user_id = ?", string(anthroveUserID)).First(&userSources).Error if err != nil { log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, @@ -317,10 +325,13 @@ func GetUserTagNodeWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, ant return nil, err } - tagFrequency := make(map[string]int) + tagFrequency := make(map[struct { + name string + typeName string + }]int) for _, userFavorite := range userFavorites { - var postTags []pgModels.Tag - err = db.WithContext(ctx).Model(&pgModels.Post{}).Where("id = ?", userFavorite.PostID).Association("Tags").Find(&postTags) + var post pgModels.Post + err = db.WithContext(ctx).Preload("Tags").First(&post, "id = ?", userFavorite.PostID).Error if err != nil { log.WithFields(log.Fields{ "post_id": userFavorite.PostID, @@ -328,17 +339,21 @@ func GetUserTagNodeWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, ant return nil, err } - for _, tag := range postTags { - tagFrequency[tag.Name]++ + for _, tag := range post.Tags { + tagFrequency[struct { + name string + typeName string + }{name: tag.Name, typeName: string(tag.Type)}]++ } } var tagsWithFrequency []graphModels.TagsWithFrequency - for tagName, frequency := range tagFrequency { + for data, frequency := range tagFrequency { tagsWithFrequency = append(tagsWithFrequency, graphModels.TagsWithFrequency{ Frequency: int64(frequency), Tags: graphModels.AnthroveTag{ - Name: tagName, + Name: data.name, + Type: data.typeName, }, }) } diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index 26f316f..531e13e 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -2,6 +2,7 @@ package postgres import ( "context" + "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" @@ -310,6 +311,40 @@ func TestGetAnthroveUser(t *testing.T) { } func TestGetSpecifiedUserSourceLink(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + source := &pgModels.Source{ + DisplayName: "e621", + Domain: "e621.net", + } + err = CreateSourceNode(ctx, gormDB, source) + if err != nil { + t.Fatal(err) + } + + expectedResult := make(map[string]graphModels.AnthroveUserRelationship) + expectedResult["e621"] = graphModels.AnthroveUserRelationship{ + UserID: "e1", + Username: "euser", + Source: graphModels.AnthroveSource{ + DisplayName: source.DisplayName, + Domain: source.Domain, + }, + } + + err = CreateUserNodeWithSourceRelation(ctx, gormDB, "1", source.Domain, expectedResult["e621"].UserID, expectedResult["e621"].Username) + if err != nil { + t.Fatal(err) + } + // Test + type args struct { ctx context.Context db *gorm.DB @@ -322,7 +357,72 @@ func TestGetSpecifiedUserSourceLink(t *testing.T) { want map[string]graphModels.AnthroveUserRelationship wantErr bool }{ - // TODO: Add test cases. + { + name: "Test 1: Valid AnthroveUserID and SourceDisplayName", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + sourceDisplayName: "e621", + }, + want: expectedResult, + wantErr: false, + }, + { + name: "Test 2: Invalid AnthroveUserID and valid SourceDisplayName", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "22", + sourceDisplayName: "e621", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 3: Valid AnthroveUserID and invalid SourceDisplayName", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + sourceDisplayName: "fa", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 4: No AnthroveUserID and Valid SourceDisplayName", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "", + sourceDisplayName: "e621", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 5: Valid AnthroveUserID and No SourceDisplayName", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + sourceDisplayName: "", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 6: No AnthroveUserID and No SourceDisplayName", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "", + sourceDisplayName: "", + }, + want: nil, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -332,13 +432,115 @@ func TestGetSpecifiedUserSourceLink(t *testing.T) { return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetSpecifiedUserSourceLink() got = %v, want %v", got, tt.want) + t.Errorf("GetSpecifiedUserSourceLink() got = %v, expectedResult %v", got, tt.want) } }) } } func TestGetUserFavoriteNodeWithPagination(t *testing.T) { + // Setup trow away containert + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + expectedResultPostsGraph := []graphModels.FavoritePost{ + { + AnthrovePost: graphModels.AnthrovePost{ + PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post1")), + Rating: "safe", + }, + }, + { + AnthrovePost: graphModels.AnthrovePost{ + PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post2")), + Rating: "safe", + }, + }, + { + AnthrovePost: graphModels.AnthrovePost{ + PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post3")), + Rating: "explicit", + }, + }, + { + AnthrovePost: graphModels.AnthrovePost{ + PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post4")), + Rating: "explicit", + }, + }, + { + AnthrovePost: graphModels.AnthrovePost{ + PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post5")), + Rating: "questionable", + }, + }, + { + AnthrovePost: graphModels.AnthrovePost{ + PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post6")), + Rating: "safe", + }, + }, + } + expectedResult := &graphModels.FavoriteList{ + Posts: expectedResultPostsGraph, + } + expectedResult2 := &graphModels.FavoriteList{ + Posts: expectedResultPostsGraph[2:], + } + expectedResult3 := &graphModels.FavoriteList{ + Posts: expectedResultPostsGraph[:3], + } + + err = CreateUser(ctx, gormDB, "1") + if err != nil { + t.Fatal(err) + } + + expectedResultPostsPg := []pgModels.Post{ + { + BaseModel: pgModels.BaseModel{ID: "Post1"}, + Rating: "safe", + }, + { + BaseModel: pgModels.BaseModel{ID: "Post2"}, + Rating: "safe", + }, + { + BaseModel: pgModels.BaseModel{ID: "Post3"}, + Rating: "explicit", + }, + { + BaseModel: pgModels.BaseModel{ID: "Post4"}, + Rating: "explicit", + }, + { + BaseModel: pgModels.BaseModel{ID: "Post5"}, + Rating: "questionable", + }, + { + BaseModel: pgModels.BaseModel{ID: "Post6"}, + Rating: "safe", + }, + } + + for _, expectedResultPost := range expectedResultPostsPg { + err = CreateAnthrovePostNode(ctx, gormDB, models.AnthrovePostID(expectedResultPost.ID), expectedResultPost.Rating) + if err != nil { + t.Fatal(err) + } + err = EstablishUserToPostLink(ctx, gormDB, "1", models.AnthrovePostID(expectedResultPost.ID)) + if err != nil { + t.Fatal(err) + } + } + + // Test type args struct { ctx context.Context db *gorm.DB @@ -352,7 +554,42 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { want *graphModels.FavoriteList wantErr bool }{ - // TODO: Add test cases. + { + name: "Test 1: Valid AnthroveUserID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + skip: 0, + limit: 2000, + }, + want: expectedResult, + wantErr: false, + }, + { + name: "Test 2: Skip first two", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + skip: 2, + limit: 2000, + }, + want: expectedResult2, + wantErr: false, + }, + { + name: "Test 3: Limit of 3", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + skip: 0, + limit: 3, + }, + want: expectedResult3, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -369,6 +606,60 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { } func TestGetUserFavoritesCount(t *testing.T) { + // Setup trow away containert + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + err = CreateUser(ctx, gormDB, "1") + if err != nil { + t.Fatal(err) + } + + expectedResultPostsPg := []pgModels.Post{ + { + BaseModel: pgModels.BaseModel{ID: "Post1"}, + Rating: "safe", + }, + { + BaseModel: pgModels.BaseModel{ID: "Post2"}, + Rating: "safe", + }, + { + BaseModel: pgModels.BaseModel{ID: "Post3"}, + Rating: "explicit", + }, + { + BaseModel: pgModels.BaseModel{ID: "Post4"}, + Rating: "explicit", + }, + { + BaseModel: pgModels.BaseModel{ID: "Post5"}, + Rating: "questionable", + }, + { + BaseModel: pgModels.BaseModel{ID: "Post6"}, + Rating: "safe", + }, + } + + for _, expectedResultPost := range expectedResultPostsPg { + err = CreateAnthrovePostNode(ctx, gormDB, models.AnthrovePostID(expectedResultPost.ID), expectedResultPost.Rating) + if err != nil { + t.Fatal(err) + } + err = EstablishUserToPostLink(ctx, gormDB, "1", models.AnthrovePostID(expectedResultPost.ID)) + if err != nil { + t.Fatal(err) + } + } + + // Test type args struct { ctx context.Context db *gorm.DB @@ -380,7 +671,36 @@ func TestGetUserFavoritesCount(t *testing.T) { want int64 wantErr bool }{ - // TODO: Add test cases. + { + name: "Test 1: Valid anthroveUserID and 6 favorite posts", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + }, + want: 6, + wantErr: false, + }, + { + name: "Test 2: Invalid anthroveUserID and 6 favorite posts", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "2", + }, + want: 0, + wantErr: false, + }, + { + name: "Test 3: no anthroveUserID and 6 favorite posts", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "", + }, + want: 0, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -397,6 +717,61 @@ func TestGetUserFavoritesCount(t *testing.T) { } func TestGetUserSourceLink(t *testing.T) { + // Setup trow away containert + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + esource := &pgModels.Source{ + DisplayName: "e621", + Domain: "e621.net", + } + err = CreateSourceNode(ctx, gormDB, esource) + if err != nil { + t.Fatal(err) + } + + fasource := &pgModels.Source{ + DisplayName: "fa", + Domain: "fa.net", + } + err = CreateSourceNode(ctx, gormDB, fasource) + if err != nil { + t.Fatal(err) + } + + expectedResult := make(map[string]graphModels.AnthroveUserRelationship) + expectedResult["e621"] = graphModels.AnthroveUserRelationship{ + UserID: "e1", + Username: "euser", + Source: graphModels.AnthroveSource{ + DisplayName: esource.DisplayName, + Domain: esource.Domain, + }, + } + expectedResult["fa"] = graphModels.AnthroveUserRelationship{ + UserID: "fa1", + Username: "fauser", + Source: graphModels.AnthroveSource{ + DisplayName: fasource.DisplayName, + Domain: fasource.Domain, + }, + } + + err = CreateUserNodeWithSourceRelation(ctx, gormDB, "1", esource.Domain, expectedResult["e621"].UserID, expectedResult["e621"].Username) + if err != nil { + t.Fatal(err) + } + err = CreateUserNodeWithSourceRelation(ctx, gormDB, "1", fasource.Domain, expectedResult["fa"].UserID, expectedResult["fa"].Username) + if err != nil { + t.Fatal(err) + } + // Test type args struct { ctx context.Context db *gorm.DB @@ -408,7 +783,16 @@ func TestGetUserSourceLink(t *testing.T) { want map[string]graphModels.AnthroveUserRelationship wantErr bool }{ - // TODO: Add test cases. + { + name: "Test 1: Get Data", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + }, + want: expectedResult, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -425,6 +809,75 @@ func TestGetUserSourceLink(t *testing.T) { } func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { + // Setup trow away containert + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + err = CreateUser(ctx, gormDB, "1") + if err != nil { + t.Fatal(err) + } + + posts := []pgModels.Post{ + {BaseModel: pgModels.BaseModel{ID: fmt.Sprintf("%-25s", "Post1")}, Rating: "safe"}, + {BaseModel: pgModels.BaseModel{ID: fmt.Sprintf("%-25s", "Post2")}, Rating: "safe"}, + {BaseModel: pgModels.BaseModel{ID: fmt.Sprintf("%-25s", "Post3")}, Rating: "explicit"}, + } + + for _, post := range posts { + err = CreateAnthrovePostNode(ctx, gormDB, models.AnthrovePostID(post.ID), post.Rating) + if err != nil { + t.Fatal(err) + } + err = EstablishUserToPostLink(ctx, gormDB, "1", models.AnthrovePostID(post.ID)) + if err != nil { + t.Fatal(err) + } + } + + tags := []pgModels.Tag{ + {Name: "JayTheFerret", Type: "artist"}, + {Name: "Ferret", Type: "species"}, + {Name: "Jay", Type: "character"}, + } + + for i, tag := range tags { + err = CreateTagNodeWitRelation(ctx, gormDB, models.AnthrovePostID(posts[i].ID), &tag) + if err != nil { + t.Fatal(err) + } + } + + expectedResult := []graphModels.TagsWithFrequency{ + { + Frequency: 1, + Tags: graphModels.AnthroveTag{ + Name: tags[0].Name, + Type: string(tags[0].Type), + }, + }, + { + Frequency: 1, + Tags: graphModels.AnthroveTag{ + Name: tags[1].Name, + Type: string(tags[1].Type), + }, + }, + { + Frequency: 1, + Tags: graphModels.AnthroveTag{ + Name: tags[2].Name, + Type: string(tags[2].Type), + }, + }, + } + + // Test type args struct { ctx context.Context db *gorm.DB @@ -436,7 +889,16 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { want []graphModels.TagsWithFrequency wantErr bool }{ - // TODO: Add test cases. + { + name: "", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + }, + want: expectedResult, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/database/migrations/001_inital_database.sql b/pkg/database/migrations/001_inital_database.sql index c78c150..7e16f9b 100644 --- a/pkg/database/migrations/001_inital_database.sql +++ b/pkg/database/migrations/001_inital_database.sql @@ -17,7 +17,7 @@ CREATE TYPE TagType AS ENUM ( CREATE TABLE "Post" ( - id CHAR(25) UNIQUE PRIMARY KEY, + id CHAR(25) PRIMARY KEY, rating Rating, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, @@ -26,7 +26,7 @@ CREATE TABLE "Post" CREATE TABLE "Source" ( - id CHAR(25) UNIQUE PRIMARY KEY, + id CHAR(25) PRIMARY KEY, display_name TEXT NULL, icon TEXT NULL, domain TEXT NOT NULL UNIQUE, @@ -46,7 +46,7 @@ CREATE TABLE "Tag" CREATE TABLE "User" ( - id TEXT UNIQUE PRIMARY KEY, + id TEXT PRIMARY KEY, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, deleted_at TIMESTAMP NULL @@ -80,8 +80,8 @@ CREATE TABLE "TagGroup" CREATE TABLE "UserFavorites" ( - user_id TEXT UNIQUE REFERENCES "User" (id), - post_id TEXT UNIQUE REFERENCES "Post" (id), + user_id TEXT REFERENCES "User" (id), + post_id TEXT REFERENCES "Post" (id), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (user_id, post_id) ); diff --git a/pkg/models/pgModels/orm.go b/pkg/models/pgModels/orm.go index c637fa5..4fd79bb 100644 --- a/pkg/models/pgModels/orm.go +++ b/pkg/models/pgModels/orm.go @@ -16,7 +16,7 @@ type BaseModel struct { func (base *BaseModel) BeforeCreate(db *gorm.DB) error { if base.ID == "" { - id, err := gonanoid.New() + id, err := gonanoid.New(25) if err != nil { return err } diff --git a/pkg/models/pgModels/userSource.go b/pkg/models/pgModels/userSource.go index a87494f..04371fe 100644 --- a/pkg/models/pgModels/userSource.go +++ b/pkg/models/pgModels/userSource.go @@ -2,6 +2,7 @@ package pgModels type UserSource struct { UserID string `gorm:"primaryKey"` + Source Source `gorm:"foreignKey:ID;references:SourceID"` SourceID string `gorm:"primaryKey"` AccountUsername string AccountID string diff --git a/test/helper.go b/test/helper.go index 4f50991..501ac62 100644 --- a/test/helper.go +++ b/test/helper.go @@ -7,6 +7,7 @@ import ( postgrescontainer "github.com/testcontainers/testcontainers-go/modules/postgres" "gorm.io/driver/postgres" "gorm.io/gorm" + "gorm.io/gorm/logger" "time" "github.com/testcontainers/testcontainers-go" @@ -73,5 +74,7 @@ func migrateDatabase(connectionString string) error { } func getGormDB(connectionString string) (*gorm.DB, error) { - return gorm.Open(postgres.Open(connectionString), &gorm.Config{}) + return gorm.Open(postgres.Open(connectionString), &gorm.Config{ + Logger: logger.Default.LogMode(logger.Info), + }) } -- 2.45.1 From 40ce69567a3dead4f7d84e2acadf6a03c2972fe7 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 14:16:03 +0200 Subject: [PATCH 042/124] dix(postgres): wrong parameters Signed-off-by: soxx --- pkg/database/postgres.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index c283bea..14c4003 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -54,7 +54,7 @@ func (p *postgresqlConnection) Connect(_ context.Context, endpoint string, usern } func (p *postgresqlConnection) AddUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error { - return postgres.CreateUserNodeWithSourceRelation(ctx, p.db, anthroveUserID, userID, sourceDomain, userID) + return postgres.CreateUserNodeWithSourceRelation(ctx, p.db, anthroveUserID, sourceDomain, userID, userID) } func (p *postgresqlConnection) AddSource(ctx context.Context, anthroveSource *graphModels.AnthroveSource) error { -- 2.45.1 From d4bec1d8c7c35f66a059e8b4e01ab9807c8965d3 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 14:36:38 +0200 Subject: [PATCH 043/124] fix(postgres): removed unneeded code that breaks the thing Signed-off-by: soxx --- internal/postgres/relationships.go | 5 ----- internal/postgres/relationships_test.go | 6 +++--- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index 7ee9fd7..b9919a1 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -2,7 +2,6 @@ package postgres import ( "context" - "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" log "github.com/sirupsen/logrus" @@ -65,10 +64,6 @@ func CheckUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID models exists := count > 0 - if !exists { - return false, fmt.Errorf("no post link exists") - } - log.WithFields(log.Fields{ "relationship_exists": exists, "relationship_anthrove_user_id": anthroveUserID, diff --git a/internal/postgres/relationships_test.go b/internal/postgres/relationships_test.go index d5033d9..29b29ba 100644 --- a/internal/postgres/relationships_test.go +++ b/internal/postgres/relationships_test.go @@ -240,7 +240,7 @@ func TestCheckUserToPostLink(t *testing.T) { anthrovePostID: "123456", }, want: false, - wantErr: true, + wantErr: false, }, { name: "Test 3: Valid AnthrovePostID and invalid AnthroveUserID", @@ -251,7 +251,7 @@ func TestCheckUserToPostLink(t *testing.T) { anthrovePostID: "1234", }, want: false, - wantErr: true, + wantErr: false, }, { name: "Test 4: Invalid AnthrovePostID and invalid AnthroveUserID", @@ -262,7 +262,7 @@ func TestCheckUserToPostLink(t *testing.T) { anthrovePostID: "123456", }, want: false, - wantErr: true, + wantErr: false, }, } for _, tt := range tests { -- 2.45.1 From 795bcbdac3c335e274dbc431e6ba2d3a078b70de Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 14:56:11 +0200 Subject: [PATCH 044/124] feat(postgres): added new each function Signed-off-by: soxx --- internal/postgres/post.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/internal/postgres/post.go b/internal/postgres/post.go index 1cd4472..1706b44 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -39,7 +39,14 @@ func CheckIfAnthrovePostNodeExistsByAnthroveID(ctx context.Context, db *gorm.DB, } func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (bool, error) { - return executeCheckQuery(ctx, db, "url = ?", sourceURL) + var size int64 + err := db.WithContext(ctx).Model(&pgModels.PostReference{}).Where("url = ?", sourceURL).Count(&size).Error + + if err != nil { + return false, err + } + + return size > 0, nil } func CheckIfAnthrovePostNodeExistsBySourceID(ctx context.Context, db *gorm.DB, sourceID string) (bool, error) { -- 2.45.1 From 2515fc50811328f43cf9cd21a4ac831d320f9562 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 15:08:42 +0200 Subject: [PATCH 045/124] fix(postgres): check if source exists before creating Signed-off-by: soxx --- internal/postgres/source.go | 2 +- internal/postgres/source_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/postgres/source.go b/internal/postgres/source.go index 1b013da..0e60a5e 100644 --- a/internal/postgres/source.go +++ b/internal/postgres/source.go @@ -16,7 +16,7 @@ func CreateSourceNode(ctx context.Context, db *gorm.DB, anthroveSource *pgModels return fmt.Errorf("anthroveSource domain is required") } - result := db.WithContext(ctx).Create(anthroveSource) + result := db.WithContext(ctx).Where(pgModels.Source{Domain: anthroveSource.Domain}).FirstOrCreate(anthroveSource) if result.Error != nil { return result.Error diff --git a/internal/postgres/source_test.go b/internal/postgres/source_test.go index 2bde71b..d0514c2 100644 --- a/internal/postgres/source_test.go +++ b/internal/postgres/source_test.go @@ -65,7 +65,7 @@ func TestCreateSourceNode(t *testing.T) { db: gormDB, anthroveSource: validAnthroveSource, }, - wantErr: true, + wantErr: false, }, } for _, tt := range tests { @@ -249,7 +249,7 @@ func checkSourceNode(got *pgModels.Source, want *pgModels.Source) bool { if want == nil && got == nil { return true } - + if got.Domain != want.Domain { return false } -- 2.45.1 From 4690ce135d7470c660dfe3c464ba8cc57279babd Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 15:15:20 +0200 Subject: [PATCH 046/124] fix(postgres): added url to SourceLink Signed-off-by: soxx --- internal/postgres/relationships.go | 4 +++- pkg/database/postgres.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index b9919a1..a109fdb 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -3,12 +3,13 @@ package postgres import ( "context" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) -func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string) error { +func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error { var source pgModels.Source var err error @@ -22,6 +23,7 @@ func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrov err = db.WithContext(ctx).Create(pgModels.PostReference{ PostID: string(anthrovePostID), SourceID: source.ID, + URL: anthrovePostRelationship.Url, }).Error if err != nil { diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 14c4003..dbba6f5 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -71,7 +71,7 @@ func (p *postgresqlConnection) AddTagWithRelationToPost(ctx context.Context, ant } func (p *postgresqlConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error { - return postgres.EstablishAnthrovePostToSourceLink(ctx, p.db, anthrovePostID, anthroveSourceDomain) + return postgres.EstablishAnthrovePostToSourceLink(ctx, p.db, anthrovePostID, anthroveSourceDomain, anthrovePostRelationship) } func (p *postgresqlConnection) LinkUserWithPost(ctx context.Context, anthroveUser *graphModels.AnthroveUser, anthrovePost *graphModels.AnthrovePost) error { -- 2.45.1 From e09d39dd02dc568e5510030e18f006ce7d62b954 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 15:18:40 +0200 Subject: [PATCH 047/124] feat(postgres): added copyright as enum Signed-off-by: soxx --- pkg/database/migrations/001_inital_database.sql | 3 ++- pkg/models/const.go | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/database/migrations/001_inital_database.sql b/pkg/database/migrations/001_inital_database.sql index 7e16f9b..5c669b6 100644 --- a/pkg/database/migrations/001_inital_database.sql +++ b/pkg/database/migrations/001_inital_database.sql @@ -12,7 +12,8 @@ CREATE TYPE TagType AS ENUM ( 'artist', 'lore', 'meta', - 'invalid' + 'invalid', + 'copyright' ); CREATE TABLE "Post" diff --git a/pkg/models/const.go b/pkg/models/const.go index 0b7d944..a9c3cf6 100644 --- a/pkg/models/const.go +++ b/pkg/models/const.go @@ -20,6 +20,7 @@ const ( Lore TagType = "lore" Meta TagType = "meta" Invalid TagType = "invalid" + Copyright TagType = "copyright" ) func (r *Rating) Convert(e621Rating string) { -- 2.45.1 From 8a2803276a3345f039d8afd87253fabef294fd04 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 15:25:22 +0200 Subject: [PATCH 048/124] fix(migration):add url to primary key Signed-off-by: soxx --- pkg/database/migrations/001_inital_database.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/database/migrations/001_inital_database.sql b/pkg/database/migrations/001_inital_database.sql index 5c669b6..a8749bf 100644 --- a/pkg/database/migrations/001_inital_database.sql +++ b/pkg/database/migrations/001_inital_database.sql @@ -62,7 +62,7 @@ CREATE TABLE "PostReference" preview_file_url TEXT, sample_file_url TEXT, source_post_id TEXT, - PRIMARY KEY (post_id, source_id) + PRIMARY KEY (post_id, source_id, url) ); CREATE TABLE "TagAlias" -- 2.45.1 From f5360d2757c247a863bc63866dc31c637a65ddb1 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 15:52:59 +0200 Subject: [PATCH 049/124] fix(migration):remove unique key for url Signed-off-by: soxx --- pkg/database/migrations/001_inital_database.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/database/migrations/001_inital_database.sql b/pkg/database/migrations/001_inital_database.sql index a8749bf..70ae07a 100644 --- a/pkg/database/migrations/001_inital_database.sql +++ b/pkg/database/migrations/001_inital_database.sql @@ -57,7 +57,7 @@ CREATE TABLE "PostReference" ( post_id TEXT REFERENCES "Post" (id), source_id TEXT REFERENCES "Source" (id), - url TEXT NOT NULL UNIQUE, + url TEXT NOT NULL, full_file_url TEXT, preview_file_url TEXT, sample_file_url TEXT, -- 2.45.1 From aea99da4847eb1f1aa21a073bea4f536b2fbe64f Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 17:50:31 +0200 Subject: [PATCH 050/124] fix(postgres): fix creating issue Signed-off-by: soxx --- internal/postgres/user.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 921af51..10b343c 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -70,7 +70,7 @@ func CreateUserNodeWithSourceRelation(ctx context.Context, db *gorm.DB, anthrove AccountID: userID, } - if err := db.WithContext(ctx).Create(&userSource).Error; err != nil { + if err := db.WithContext(ctx).FirstOrCreate(&userSource).Error; err != nil { log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, "source_domain": sourceDomain, -- 2.45.1 From b86c6671567e8d421ff9587702341ee0b933662b Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 22:54:47 +0200 Subject: [PATCH 051/124] fix(postgres): CheckIfAnthrovePostNodeExistsBySourceURL now working as intended Signed-off-by: soxx --- internal/postgres/post.go | 23 ++++++++++++++++++----- pkg/database/postgres.go | 3 +-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/internal/postgres/post.go b/internal/postgres/post.go index 1706b44..cf7a58c 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -2,8 +2,10 @@ package postgres import ( "context" + "errors" "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" log "github.com/sirupsen/logrus" "gorm.io/gorm" @@ -38,15 +40,26 @@ func CheckIfAnthrovePostNodeExistsByAnthroveID(ctx context.Context, db *gorm.DB, return executeCheckQuery(ctx, db, "id = ?", string(anthrovePostID)) } -func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (bool, error) { - var size int64 - err := db.WithContext(ctx).Model(&pgModels.PostReference{}).Where("url = ?", sourceURL).Count(&size).Error +func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (*graphModels.AnthrovePost, bool, error) { + var post pgModels.Post + err := db.WithContext(ctx).Model(&pgModels.Post{}).InnerJoins("References", db.Where("url = ?", sourceURL)).First(&post).Error if err != nil { - return false, err + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, false, nil + } + return nil, false, err } - return size > 0, nil + pgPost := &graphModels.AnthrovePost{ + PostID: models.AnthrovePostID(post.ID), + Rating: post.Rating, + } + + //TODO Now test it! :D + // Naaa + // D: + return pgPost, true, nil } func CheckIfAnthrovePostNodeExistsBySourceID(ctx context.Context, db *gorm.DB, sourceID string) (bool, error) { diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index dbba6f5..aec5911 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -89,8 +89,7 @@ func (p *postgresqlConnection) CheckPostNodeExistsByAnthroveID(ctx context.Conte // CheckPostNodeExistsBySourceURL NOT WORKING! TODO! func (p *postgresqlConnection) CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*graphModels.AnthrovePost, bool, error) { - var post graphModels.AnthrovePost - exists, err := postgres.CheckIfAnthrovePostNodeExistsBySourceURL(ctx, p.db, sourceUrl) + post, exists, err := postgres.CheckIfAnthrovePostNodeExistsBySourceURL(ctx, p.db, sourceUrl) return &post, exists, err } -- 2.45.1 From 5e501b20036f533c5ffcadfff1c1f0e8d0f6dde8 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 22:57:05 +0200 Subject: [PATCH 052/124] fix(postgres): ** whyy Signed-off-by: soxx --- internal/postgres/post.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/postgres/post.go b/internal/postgres/post.go index cf7a58c..3fc9ec1 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -40,7 +40,7 @@ func CheckIfAnthrovePostNodeExistsByAnthroveID(ctx context.Context, db *gorm.DB, return executeCheckQuery(ctx, db, "id = ?", string(anthrovePostID)) } -func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (*graphModels.AnthrovePost, bool, error) { +func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (graphModels.AnthrovePost, bool, error) { var post pgModels.Post err := db.WithContext(ctx).Model(&pgModels.Post{}).InnerJoins("References", db.Where("url = ?", sourceURL)).First(&post).Error @@ -51,7 +51,7 @@ func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, return nil, false, err } - pgPost := &graphModels.AnthrovePost{ + pgPost := graphModels.AnthrovePost{ PostID: models.AnthrovePostID(post.ID), Rating: post.Rating, } -- 2.45.1 From 0b7b6beccdccda09ebebc93b3c5d016ce3123225 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 22:58:52 +0200 Subject: [PATCH 053/124] fix(postgres): Update CheckIfAnthrovePostNodeExistsBySourceURL to return pointer instead of value Signed-off-by: soxx --- internal/postgres/post.go | 4 ++-- pkg/database/postgres.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/postgres/post.go b/internal/postgres/post.go index 3fc9ec1..d8158d9 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -40,7 +40,7 @@ func CheckIfAnthrovePostNodeExistsByAnthroveID(ctx context.Context, db *gorm.DB, return executeCheckQuery(ctx, db, "id = ?", string(anthrovePostID)) } -func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (graphModels.AnthrovePost, bool, error) { +func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (*graphModels.AnthrovePost, bool, error) { var post pgModels.Post err := db.WithContext(ctx).Model(&pgModels.Post{}).InnerJoins("References", db.Where("url = ?", sourceURL)).First(&post).Error @@ -59,7 +59,7 @@ func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, //TODO Now test it! :D // Naaa // D: - return pgPost, true, nil + return &pgPost, true, nil } func CheckIfAnthrovePostNodeExistsBySourceID(ctx context.Context, db *gorm.DB, sourceID string) (bool, error) { diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index aec5911..62a4d2c 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -90,7 +90,7 @@ func (p *postgresqlConnection) CheckPostNodeExistsByAnthroveID(ctx context.Conte // CheckPostNodeExistsBySourceURL NOT WORKING! TODO! func (p *postgresqlConnection) CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*graphModels.AnthrovePost, bool, error) { post, exists, err := postgres.CheckIfAnthrovePostNodeExistsBySourceURL(ctx, p.db, sourceUrl) - return &post, exists, err + return post, exists, err } // CheckPostNodeExistsBySourceID NOT WORKING! TODO! -- 2.45.1 From c359b4636ef13939bff7e710bd18663fa278210c Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 23:18:33 +0200 Subject: [PATCH 054/124] fix(postgres): prefilled posts with empty Signed-off-by: soxx --- internal/postgres/post.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/postgres/post.go b/internal/postgres/post.go index d8158d9..c5983dc 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -41,7 +41,7 @@ func CheckIfAnthrovePostNodeExistsByAnthroveID(ctx context.Context, db *gorm.DB, } func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (*graphModels.AnthrovePost, bool, error) { - var post pgModels.Post + post := pgModels.Post{} err := db.WithContext(ctx).Model(&pgModels.Post{}).InnerJoins("References", db.Where("url = ?", sourceURL)).First(&post).Error if err != nil { -- 2.45.1 From c07fd69f4f206c21a9e71a3c1e2577d004c56bfa Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 23:25:55 +0200 Subject: [PATCH 055/124] fix(postgres): CheckIfAnthrovePostNodeExistsBySourceURL function to use PostReference model Signed-off-by: soxx --- internal/postgres/post.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/postgres/post.go b/internal/postgres/post.go index c5983dc..3ed43a5 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -41,8 +41,8 @@ func CheckIfAnthrovePostNodeExistsByAnthroveID(ctx context.Context, db *gorm.DB, } func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (*graphModels.AnthrovePost, bool, error) { - post := pgModels.Post{} - err := db.WithContext(ctx).Model(&pgModels.Post{}).InnerJoins("References", db.Where("url = ?", sourceURL)).First(&post).Error + postRef := pgModels.PostReference{} + err := db.WithContext(ctx).Model(&pgModels.PostReference{}).Where("url = ?", sourceURL).First(&postRef).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { @@ -51,6 +51,13 @@ func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, return nil, false, err } + var post pgModels.Post + err = db.WithContext(ctx).First(&post, "id = ?", postRef.PostID).Error + + if err != nil { + return nil, false, err + } + pgPost := graphModels.AnthrovePost{ PostID: models.AnthrovePostID(post.ID), Rating: post.Rating, -- 2.45.1 From 3c17c6043972501546d0a0c0281958db42ac1ac9 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 23:35:41 +0200 Subject: [PATCH 056/124] fix(postgres): Update postgres.go to use silent logger for GORM configuration Signed-off-by: soxx --- pkg/database/postgres.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 62a4d2c..ab22d85 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -14,6 +14,7 @@ import ( log "github.com/sirupsen/logrus" gormPostgres "gorm.io/driver/postgres" "gorm.io/gorm" + logger2 "gorm.io/gorm/logger" ) //go:embed migrations/*.sql @@ -42,7 +43,9 @@ func (p *postgresqlConnection) Connect(_ context.Context, endpoint string, usern log.Infof("OtterSpace: migration compleate") - db, err := gorm.Open(gormPostgres.Open(dsn), &gorm.Config{}) + db, err := gorm.Open(gormPostgres.Open(dsn), &gorm.Config{ + Logger: logger2.Default.LogMode(logger2.Silent), + }) p.db = db if err != nil { return err -- 2.45.1 From 536f7c044327a8f1432c1c1ec7a870e063c8a9f1 Mon Sep 17 00:00:00 2001 From: soxx Date: Fri, 21 Jun 2024 23:48:18 +0200 Subject: [PATCH 057/124] fix(postgres): Update database logger in postgres.go to include slow queries and error handling Signed-off-by: soxx --- pkg/database/postgres.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index ab22d85..ff4eb16 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -15,6 +15,9 @@ import ( gormPostgres "gorm.io/driver/postgres" "gorm.io/gorm" logger2 "gorm.io/gorm/logger" + log2 "log" + "os" + "time" ) //go:embed migrations/*.sql @@ -43,8 +46,15 @@ func (p *postgresqlConnection) Connect(_ context.Context, endpoint string, usern log.Infof("OtterSpace: migration compleate") + dbLogger := logger2.New(log2.New(os.Stdout, "\r\n", log2.LstdFlags), logger2.Config{ + SlowThreshold: 200 * time.Millisecond, + LogLevel: logger2.Warn, + IgnoreRecordNotFoundError: true, + Colorful: true, + }) + db, err := gorm.Open(gormPostgres.Open(dsn), &gorm.Config{ - Logger: logger2.Default.LogMode(logger2.Silent), + Logger: dbLogger, }) p.db = db if err != nil { -- 2.45.1 From 58dcf94d492739221d1e08eee80172756a51d21f Mon Sep 17 00:00:00 2001 From: soxx Date: Sat, 22 Jun 2024 22:06:36 +0200 Subject: [PATCH 058/124] refactor(postgres): removed old graph related code Signed-off-by: soxx --- internal/graph/logger.go | 46 -- internal/graph/post.go | 116 ----- internal/graph/relationships.go | 100 ---- internal/graph/source.go | 113 ----- internal/graph/tag.go | 84 ---- internal/graph/user.go | 454 ------------------ internal/postgres/post.go | 13 +- internal/postgres/relationships.go | 9 +- internal/postgres/relationships_test.go | 3 +- internal/postgres/source.go | 14 +- internal/postgres/source_test.go | 20 +- internal/postgres/tag.go | 13 +- internal/postgres/tag_test.go | 11 +- internal/postgres/user.go | 57 ++- internal/postgres/user_test.go | 83 ++-- internal/utils/modelConvert.go | 60 --- pkg/database/database.go | 58 +-- pkg/database/graph.go | 123 ----- .../migrations/001_inital_database.sql | 8 +- pkg/models/README.md | 84 ---- pkg/models/{pgModels => }/orm.go | 2 +- pkg/models/pgModels/userSource.go | 13 - pkg/models/{pgModels => }/post.go | 8 +- pkg/models/{pgModels => }/postReference.go | 2 +- pkg/models/{pgModels => }/source.go | 2 +- pkg/models/{pgModels => }/tag.go | 19 +- pkg/models/{pgModels => }/user.go | 2 +- pkg/models/{pgModels => }/userFavorite.go | 6 +- pkg/models/userSource.go | 14 + 29 files changed, 164 insertions(+), 1373 deletions(-) delete mode 100644 internal/graph/logger.go delete mode 100644 internal/graph/post.go delete mode 100644 internal/graph/relationships.go delete mode 100644 internal/graph/source.go delete mode 100644 internal/graph/tag.go delete mode 100644 internal/graph/user.go delete mode 100644 internal/utils/modelConvert.go delete mode 100644 pkg/database/graph.go delete mode 100644 pkg/models/README.md rename pkg/models/{pgModels => }/orm.go (95%) delete mode 100644 pkg/models/pgModels/userSource.go rename pkg/models/{pgModels => }/post.go (65%) rename pkg/models/{pgModels => }/postReference.go (95%) rename pkg/models/{pgModels => }/source.go (95%) rename pkg/models/{pgModels => }/tag.go (53%) rename pkg/models/{pgModels => }/user.go (92%) rename pkg/models/{pgModels => }/userFavorite.go (69%) create mode 100644 pkg/models/userSource.go diff --git a/internal/graph/logger.go b/internal/graph/logger.go deleted file mode 100644 index 914db3a..0000000 --- a/internal/graph/logger.go +++ /dev/null @@ -1,46 +0,0 @@ -package graph - -import ( - "fmt" - - neo4jLog "github.com/neo4j/neo4j-go-driver/v5/neo4j/log" - log "github.com/sirupsen/logrus" -) - -type graphLogger struct { - graphDebug bool -} - -func NewGraphLogger(graphDebug bool) neo4jLog.Logger { - return &graphLogger{graphDebug: graphDebug} -} - -func (n graphLogger) Error(name string, id string, err error) { - log.WithFields(log.Fields{ - "name": name, - "id": id, - }).Errorf("database: %s", err) -} - -func (n graphLogger) Warnf(name string, id string, msg string, args ...any) { - log.WithFields(log.Fields{ - "name": name, - "id": id, - }).Warnf("database: %v", fmt.Sprintf(msg, args...)) -} - -func (n graphLogger) Infof(name string, id string, msg string, args ...any) { - log.WithFields(log.Fields{ - "name": name, - "id": id, - }).Infof("database: %v", fmt.Sprintf(msg, args...)) -} - -func (n graphLogger) Debugf(name string, id string, msg string, args ...any) { - if n.graphDebug { - log.WithFields(log.Fields{ - "name": name, - "id": id, - }).Debugf("database: %v", fmt.Sprintf(msg, args...)) - } -} diff --git a/internal/graph/post.go b/internal/graph/post.go deleted file mode 100644 index d263928..0000000 --- a/internal/graph/post.go +++ /dev/null @@ -1,116 +0,0 @@ -package graph - -import ( - "context" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" - "github.com/neo4j/neo4j-go-driver/v5/neo4j" - log "github.com/sirupsen/logrus" -) - -func CreateAnthrovePostNode(ctx context.Context, driver neo4j.DriverWithContext, anthrovePost *graphModels.AnthrovePost) error { - query := ` - CREATE (newPostNode:AnthrovePost {post_id: $anthrove_post_id, rating: $anthrove_rating}) - ` - - params := map[string]any{ - "anthrove_post_id": anthrovePost.PostID, - "anthrove_rating": anthrovePost.Rating, - } - - _, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return err - } - - log.WithFields(log.Fields{ - "anthrove_post_id": anthrovePost.PostID, - "anthrove_post_rating": anthrovePost.Rating, - }).Trace("database: created anthrove post") - - return nil -} - -func CheckIfAnthrovePostNodeExistsByAnthroveID(ctx context.Context, driver neo4j.DriverWithContext, anthrovePost *graphModels.AnthrovePost) (*graphModels.AnthrovePost, bool, error) { - query := ` - OPTIONAL MATCH (postNode:AnthrovePost {post_id: $anthrove_post_id}) - RETURN postNode.post_id AS AnthrovePostID - ` - - params := map[string]any{ - "anthrove_post_id": anthrovePost.PostID, - } - - anthrovePost, exists, err := executeCheckQuery(ctx, driver, query, params) - if err != nil { - return nil, false, err - } - - return anthrovePost, exists, nil -} - -func CheckIfAnthrovePostNodeExistsBySourceURl(ctx context.Context, driver neo4j.DriverWithContext, sourceUrl string) (*graphModels.AnthrovePost, bool, error) { - query := ` - OPTIONAL MATCH (postNode:AnthrovePost)<-[:REFERENCE {url: $source_url}]-() - RETURN postNode.post_id AS AnthrovePostID - ` - - params := map[string]any{ - "source_url": sourceUrl, - } - anthrovePost, exists, err := executeCheckQuery(ctx, driver, query, params) - if err != nil { - return nil, false, err - } - - return anthrovePost, exists, nil -} - -func CheckIfAnthrovePostNodeExistsBySourceID(ctx context.Context, driver neo4j.DriverWithContext, sourcePostID string) (*graphModels.AnthrovePost, bool, error) { - query := ` - OPTIONAL MATCH (postNode:AnthrovePost)<-[:REFERENCE {source_post_id: $source_post_id}]-() - RETURN postNode.post_id AS AnthrovePostID - ` - - params := map[string]any{ - "source_post_id": sourcePostID, - } - - anthrovePost, exists, err := executeCheckQuery(ctx, driver, query, params) - if err != nil { - return nil, false, err - } - - return anthrovePost, exists, nil -} - -func executeCheckQuery(ctx context.Context, driver neo4j.DriverWithContext, query string, params map[string]any) (*graphModels.AnthrovePost, bool, error) { - - var anthrovePost graphModels.AnthrovePost - - result, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return &anthrovePost, false, err - } - - record := result.Records - - anthrovePostID, isNil, err := neo4j.GetRecordValue[string](record[0], "AnthrovePostID") - exists := !isNil - if err != nil { - return &anthrovePost, exists, err - } - - anthrovePost.PostID = models.AnthrovePostID(anthrovePostID) - - log.WithFields(log.Fields{ - "anthrove_post_id": anthrovePost.PostID, - "anthrove_post_exists": exists, - }).Trace("database: checked if post exists") - - if !exists { - return nil, exists, nil - } - - return &anthrovePost, exists, nil -} diff --git a/internal/graph/relationships.go b/internal/graph/relationships.go deleted file mode 100644 index d9ea521..0000000 --- a/internal/graph/relationships.go +++ /dev/null @@ -1,100 +0,0 @@ -package graph - -import ( - "context" - "fmt" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" - "github.com/neo4j/neo4j-go-driver/v5/neo4j" - log "github.com/sirupsen/logrus" -) - -func EstablishAnthrovePostToSourceLink(ctx context.Context, driver neo4j.DriverWithContext, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error { - query := ` - MATCH (sourceNode:Source {domain: $source_url}) - MATCH (postNode:AnthrovePost {post_id: $anthrove_post_id}) - MERGE (sourceNode)-[:REFERENCE {url: $source_post_url, source_post_id: $source_post_id}]->(postNode) - ` - - params := map[string]any{ - "source_url": anthroveSourceDomain, - "anthrove_post_id": anthrovePostID, - "source_post_url": anthrovePostRelationship.Url, - "source_post_id": anthrovePostRelationship.PostID, - } - - _, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return err - } - - log.WithFields(log.Fields{ - "source_url": anthroveSourceDomain, - "anthrove_post_id": anthrovePostID, - "source_post_url": anthrovePostRelationship.Url, - "source_post_id": anthrovePostRelationship.PostID, - }).Trace("database: creating anthrove post to source link") - - return nil -} - -func EstablishUserToPostLink(ctx context.Context, driver neo4j.DriverWithContext, anthroveUser *graphModels.AnthroveUser, anthrovePost *graphModels.AnthrovePost) error { - - query := ` - MATCH (user:User {user_id: $anthrove_user_id}) - MATCH (anthrovePost:AnthrovePost {post_id: $anthrove_post_id}) - MERGE (user)-[:FAV]->(anthrovePost) - ` - - params := map[string]any{ - "anthrove_post_id": anthrovePost.PostID, - "anthrove_user_id": anthroveUser.UserID, - } - - _, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return err - } - - log.WithFields(log.Fields{ - "anthrove_post_id": anthrovePost.PostID, - "anthrove_user_id": anthroveUser.UserID, - }).Trace("database: created user to post link") - - return nil -} - -func CheckUserToPostLink(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) { - query := ` - OPTIONAL MATCH (:User {user_id: $anthrove_user_id})-[f:FAV]->(:AnthrovePost)<-[:REFERENCE{source_post_id: $source_post_id}]-(:Source{domain: $source_domain}) - RETURN COUNT(f) > 0 AS hasRelationship - ` - - params := map[string]any{ - "anthrove_user_id": anthroveUserID, - "source_post_id": sourcePostID, - "source_domain": sourceUrl, - } - - result, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return false, err - } - - if len(result.Records) == 0 { - return false, fmt.Errorf("no records found") - } - - exists, _, err := neo4j.GetRecordValue[bool](result.Records[0], "hasRelationship") - if err != nil { - return false, err - } - - log.WithFields(log.Fields{ - "relationship_exists": exists, - "relationship_anthrove_user_id": anthroveUserID, - "relationship_e621_post_id": "", - }).Trace("database: checked user post relationship") - - return exists, nil -} diff --git a/internal/graph/source.go b/internal/graph/source.go deleted file mode 100644 index 5ed8fa6..0000000 --- a/internal/graph/source.go +++ /dev/null @@ -1,113 +0,0 @@ -package graph - -import ( - "context" - "fmt" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" - - "github.com/neo4j/neo4j-go-driver/v5/neo4j" - log "github.com/sirupsen/logrus" -) - -func CreateSourceNode(ctx context.Context, driver neo4j.DriverWithContext, anthroveSource *graphModels.AnthroveSource) error { - query := ` - MERGE (sourceNode:Source {domain: $source_url}) - ON CREATE SET sourceNode.domain = $source_url, sourceNode.display_name = $source_display_name, sourceNode.icon = $source_icon - ` - params := map[string]any{ - "source_url": anthroveSource.Domain, - "source_display_name": anthroveSource.DisplayName, - "source_icon": anthroveSource.Icon, - } - - _, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return fmt.Errorf("database: %w", err) - } - - log.WithFields(log.Fields{ - "node_source_url": anthroveSource.Domain, - "node_source_displayName": anthroveSource.DisplayName, - "node_source_icon": anthroveSource.Icon, - }).Trace("database: created source node") - - return nil -} - -func GetAllSourceNodes(ctx context.Context, driver neo4j.DriverWithContext) ([]graphModels.AnthroveSource, error) { - var sources []graphModels.AnthroveSource - - query := ` - MATCH (s:Source) - RETURN s as source - ` - params := map[string]any{} - - result, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return nil, err - } - - if len(result.Records) == 0 { - return nil, nil - } - - for i := range result.Records { - record := result.Records[i] - - source, _, err := neo4j.GetRecordValue[neo4j.Node](record, "source") - if err != nil { - return nil, err - } - - sources = append(sources, graphModels.AnthroveSource{ - DisplayName: source.Props["display_name"].(string), - Domain: source.Props["domain"].(string), - Icon: source.Props["icon"].(string), - }) - - } - - log.WithFields(log.Fields{ - "tag_amount": len(sources), - }).Trace("database: created tag node") - - return sources, nil -} - -func GetSourceNodesByURL(ctx context.Context, driver neo4j.DriverWithContext, sourceUrl string) (*graphModels.AnthroveSource, error) { - - var source graphModels.AnthroveSource - - query := ` - MATCH (s:Source {domain: $source_url}) - RETURN s as source - ` - params := map[string]any{ - "source_url": sourceUrl, - } - - result, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return nil, err - } - - if len(result.Records) == 0 { - return nil, fmt.Errorf("source not found") - } - - record, _, err := neo4j.GetRecordValue[neo4j.Node](result.Records[0], "source") - if err != nil { - return nil, err - } - - source.DisplayName = record.Props["display_name"].(string) - source.Domain = record.Props["domain"].(string) - source.Icon = record.Props["icon"].(string) - - log.WithFields(log.Fields{ - "source_url": sourceUrl, - }).Trace("database: got source node") - - return &source, nil -} diff --git a/internal/graph/tag.go b/internal/graph/tag.go deleted file mode 100644 index cc9142c..0000000 --- a/internal/graph/tag.go +++ /dev/null @@ -1,84 +0,0 @@ -package graph - -import ( - "context" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" - "github.com/neo4j/neo4j-go-driver/v5/neo4j" - log "github.com/sirupsen/logrus" -) - -func CreateTagNodeWitRelation(ctx context.Context, driver neo4j.DriverWithContext, anthrovePostID models.AnthrovePostID, anthroveTag *graphModels.AnthroveTag) error { - query := ` - MATCH (anthrovePost:AnthrovePost {post_id: $anthrove_post_id}) - MERGE (tagNode:Tag {name: $tag_name, type: $tag_type}) - MERGE (anthrovePost)-[:HAS]->(tagNode) - ` - params := map[string]interface{}{ - "tag_name": anthroveTag.Name, - "tag_type": anthroveTag.Type, - "anthrove_post_id": anthrovePostID, - } - - _, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return err - } - - log.WithFields(log.Fields{ - "anthrove_post_id": anthrovePostID, - "tag_name": anthroveTag.Name, - "tag_type": anthroveTag.Type, - }).Trace("database: created tag node") - - return nil -} - -func GetTags(ctx context.Context, driver neo4j.DriverWithContext) ([]graphModels.TagsWithFrequency, error) { - var userTags []graphModels.TagsWithFrequency - - query := ` - MATCH (:AnthrovePost)-[:HAS]->(t:Tag) - RETURN t as tag, COUNT(t) AS frequency - ORDER BY frequency DESC - ` - params := map[string]any{} - - result, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return nil, err - } - - if len(result.Records) == 0 { - return nil, nil - } - - for i := range result.Records { - record := result.Records[i] - - tag, _, err := neo4j.GetRecordValue[neo4j.Node](record, "tag") - if err != nil { - return nil, err - } - - frequency, _, err := neo4j.GetRecordValue[int64](record, "frequency") - if err != nil { - return nil, err - } - - userTags = append(userTags, graphModels.TagsWithFrequency{ - Frequency: frequency, - Tags: graphModels.AnthroveTag{ - Name: tag.Props["name"].(string), - Type: tag.Props["type"].(string), - }, - }) - - } - - log.WithFields(log.Fields{ - "tag_amount": len(userTags), - }).Trace("database: created tag node") - - return userTags, nil -} diff --git a/internal/graph/user.go b/internal/graph/user.go deleted file mode 100644 index a136de3..0000000 --- a/internal/graph/user.go +++ /dev/null @@ -1,454 +0,0 @@ -package graph - -import ( - "context" - "fmt" - "git.dragse.it/anthrove/otter-space-sdk/internal/utils" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" - "github.com/neo4j/neo4j-go-driver/v5/neo4j" - log "github.com/sirupsen/logrus" -) - -func CreateUserNodeWithSourceRelation(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error { - query := ` - MATCH (userNode:User {user_id: $anthrove_user_id}) - MATCH (sourceNode:Source {domain: $source_domain}) - MERGE (userNode)-[r:HAS_ACCOUNT_AT {username: $source_user_name, user_id: $source_user_id}]->(sourceNode) - ` - params := map[string]any{ - "anthrove_user_id": anthroveUserID, - "source_user_id": userID, - "source_user_name": username, - "source_domain": sourceDomain, - } - - _, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return err - } - - var anthroveUserRelationship []graphModels.AnthroveUserRelationship - - anthroveUserRelationship = append(anthroveUserRelationship, graphModels.AnthroveUserRelationship{ - UserID: userID, - Username: username, - ScrapeTimeInterval: "", - Source: graphModels.AnthroveSource{ - DisplayName: "", - Domain: sourceDomain, - Icon: "", - }, - }) - - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - "source_user_id": userID, - "source_user_name": username, - "source_domain": sourceDomain, - }).Trace("database: crated user with relationship") - - return nil -} - -func GetUserFavoritesCount(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID) (int64, error) { - var userFavoriteCount int64 - - query := ` - MATCH (userNode:User {user_id: $anthrove_user_id}) - MATCH (userNode)-[:FAV]->(favPost:AnthrovePost) - MATCH (sourceNode)-[:REFERENCE]->(favPost) - RETURN count( DISTINCT favPost) AS FavoritePostsCount - ` - - params := map[string]any{ - "anthrove_user_id": anthroveUserID, - } - - result, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return 0, err - } - - if len(result.Records) == 0 { - // no matches -> user does not exist, return count 0 - return userFavoriteCount, err - } - - record := result.Records[0] - - userFavoriteCount, _, err = neo4j.GetRecordValue[int64](record, "FavoritePostsCount") - if err != nil { - return userFavoriteCount, err - } - - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - "anthrove_user_fav_count": userFavoriteCount, - }).Trace("database: got user favorite count") - - return userFavoriteCount, nil -} - -func GetUserSourceLink(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID) (map[string]graphModels.AnthroveUserRelationship, error) { - - userSource := make(map[string]graphModels.AnthroveUserRelationship) - - query := ` - MATCH (user:User{user_id: $anthrove_user_id})-[r:HAS_ACCOUNT_AT]->(s:Source) - RETURN toString(r.user_id) AS sourceUserID, toString(r.username) AS sourceUsername, s as source; - ` - params := map[string]any{ - "anthrove_user_id": anthroveUserID, - } - - result, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return nil, err - } - - if len(result.Records) == 0 { - return nil, fmt.Errorf("user has no relations") - } - - for i := range result.Records { - record := result.Records[i] - source, _, err := neo4j.GetRecordValue[neo4j.Node](record, "source") - if err != nil { - return nil, err - } - sourceUserID, _, err := neo4j.GetRecordValue[string](record, "sourceUserID") - if err != nil { - return nil, err - } - sourceUsername, _, err := neo4j.GetRecordValue[string](record, "sourceUsername") - if err != nil { - return nil, err - } - - displayName := source.Props["display_name"].(string) - domain := source.Props["domain"].(string) - icon := source.Props["icon"].(string) - - anthroveSourceUser := graphModels.AnthroveUserRelationship{ - UserID: sourceUserID, - Username: sourceUsername, - Source: graphModels.AnthroveSource{ - DisplayName: displayName, - Domain: domain, - Icon: icon, - }, - } - userSource[displayName] = anthroveSourceUser - } - - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - "anthrove_data": userSource, - }).Trace("database: got user favorite count") - - return userSource, nil -} - -func GetSpecifiedUserSourceLink(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]graphModels.AnthroveUserRelationship, error) { - - userSource := make(map[string]graphModels.AnthroveUserRelationship) - - query := ` - MATCH (user:User{user_id: $anthrove_user_id})-[r:HAS_ACCOUNT_AT]->(s:Source{display_name: $source_display_name}) - RETURN toString(r.user_id) AS sourceUserID, toString(r.username) AS sourceUsername, s as source; - ` - params := map[string]any{ - "anthrove_user_id": anthroveUserID, - "source_display_name": sourceDisplayName, - } - - result, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return nil, err - } - - if len(result.Records) == 0 { - return nil, fmt.Errorf("user has no relations with the source %s", sourceDisplayName) - } - - for i := range result.Records { - record := result.Records[i] - source, _, err := neo4j.GetRecordValue[neo4j.Node](record, "source") - if err != nil { - return nil, err - } - sourceUserID, _, err := neo4j.GetRecordValue[string](record, "sourceUserID") - if err != nil { - return nil, err - } - sourceUsername, _, err := neo4j.GetRecordValue[string](record, "sourceUsername") - if err != nil { - return nil, err - } - - displayName := source.Props["display_name"].(string) - domain := source.Props["domain"].(string) - icon := source.Props["icon"].(string) - - anthroveSourceUser := graphModels.AnthroveUserRelationship{ - UserID: sourceUserID, - Username: sourceUsername, - Source: graphModels.AnthroveSource{ - DisplayName: displayName, - Domain: domain, - Icon: icon, - }, - } - userSource[displayName] = anthroveSourceUser - } - - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - "anthrove_data": userSource, - }).Trace("database: got user favorite count") - - return userSource, nil -} - -func GetAnthroveUser(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID) (*graphModels.AnthroveUser, error) { - var err error - var anthroveUser graphModels.AnthroveUser - var userSources graphModels.AnthroveSource - userRelationships := make([]graphModels.AnthroveUserRelationship, 0) - - query := ` - MATCH (user:User{user_id: $anthrove_user_id})-[relation:HAS_ACCOUNT_AT]->(source:Source) - RETURN user as User, relation as Relation, source as Source; - ` - params := map[string]any{ - "anthrove_user_id": anthroveUserID, - } - - result, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return nil, err - } - - if len(result.Records) == 0 { - return nil, fmt.Errorf("user has no relations") - } - - for i := range result.Records { - record := result.Records[i] - - user, _, err := neo4j.GetRecordValue[neo4j.Node](record, "User") - if err != nil { - return nil, err - } - relation, _, err := neo4j.GetRecordValue[neo4j.Relationship](record, "Relation") - if err != nil { - return nil, err - } - source, _, err := neo4j.GetRecordValue[neo4j.Node](record, "Source") - if err != nil { - return nil, err - } - - userRelationships = append(userRelationships, graphModels.AnthroveUserRelationship{ - UserID: fmt.Sprintf("%v", utils.GetOrDefault(relation.Props, "user_id", "")), - Username: utils.GetOrDefault(relation.Props, "username", "").(string), - ScrapeTimeInterval: utils.GetOrDefault(relation.Props, "scrape_time_interval", "").(string), - }) - - userSources = graphModels.AnthroveSource{ - DisplayName: utils.GetOrDefault(source.Props, "display_name", "").(string), - Domain: utils.GetOrDefault(source.Props, "domain", "").(string), - Icon: utils.GetOrDefault(source.Props, "icon", "").(string), - } - - anthroveUser.UserID = models.AnthroveUserID(utils.GetOrDefault(user.Props, "user_id", "").(string)) - anthroveUser.Relationship = userRelationships - - for j := range userRelationships { - anthroveUser.Relationship[j].Source = userSources - } - - } - - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - }).Trace("database: got anthrove user") - - return &anthroveUser, nil - -} - -func GetAllAnthroveUserIDs(ctx context.Context, driver neo4j.DriverWithContext) ([]models.AnthroveUserID, error) { - var err error - var anthroveUsers []models.AnthroveUserID - - query := ` - MATCH (anthroveUser:User) - RETURN anthroveUser - ` - result, err := neo4j.ExecuteQuery(ctx, driver, query, nil, neo4j.EagerResultTransformer) - if err != nil { - return nil, err - } - - if len(result.Records) == 0 { - log.Warnf("No users found, this should not be happening!") - return []models.AnthroveUserID{}, nil - } - - for i := range result.Records { - record := result.Records[i] - - user, _, err := neo4j.GetRecordValue[neo4j.Node](record, "anthroveUser") - if err != nil { - return nil, err - } - - anthroveUsers = append(anthroveUsers, models.AnthroveUserID(fmt.Sprintf(user.Props["user_id"].(string)))) - } - - log.WithFields(log.Fields{ - "anthrove_user_id_count": len(anthroveUsers), - }).Trace("database: got al anthrove user IDs") - - return anthroveUsers, nil - -} - -func GetUserFavoriteNodeWithPagination(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID, skip int, limit int) (*graphModels.FavoriteList, error) { - var err error - var favoritePosts []graphModels.FavoritePost - - query := ` - CALL { - MATCH (user:User{user_id: $anthrove_user_id})-[r:FAV]->(p:AnthrovePost) - RETURN p.post_id AS post_id - ORDER BY id(p) ASC - SKIP $skip - LIMIT $limit - } - WITH collect(post_id) AS faves - MATCH (a:AnthrovePost)<-[r:REFERENCE]-(s:Source) - WHERE a.post_id in faves - RETURN a AS anthrovePost, r AS postRelation, s AS Source - ORDER BY id(a) ASC - ` - params := map[string]any{ - "anthrove_user_id": anthroveUserID, - "limit": limit, - "skip": skip, - } - - result, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return nil, err - } - - if len(result.Records) == 0 { - return nil, nil - } - - for i := range result.Records { - record := result.Records[i] - - anthrovePost, _, err := neo4j.GetRecordValue[neo4j.Node](record, "anthrovePost") - if err != nil { - return nil, err - } - - postRelation, _, err := neo4j.GetRecordValue[neo4j.Relationship](record, "postRelation") - if err != nil { - return nil, err - } - - source, _, err := neo4j.GetRecordValue[neo4j.Node](record, "Source") - if err != nil { - return nil, err - } - - if len(favoritePosts) != 0 && favoritePosts[len(favoritePosts)-1].AnthrovePost.PostID == models.AnthrovePostID(anthrovePost.Props["post_id"].(string)) { - favoritePosts[len(favoritePosts)-1].Relations = append(favoritePosts[len(favoritePosts)-1].Relations, graphModels.FavoriteRelations{ - SourcesID: source.Props["display_name"].(string), - Relations: graphModels.AnthrovePostRelationship{ - PostID: postRelation.Props["source_post_id"].(string), - Url: postRelation.Props["url"].(string), - }, - }) - } else { - favoritePosts = append(favoritePosts, graphModels.FavoritePost{ - AnthrovePost: graphModels.AnthrovePost{ - PostID: models.AnthrovePostID(anthrovePost.Props["post_id"].(string)), - Rating: models.Rating(anthrovePost.Props["rating"].(string)), - }, - Relations: []graphModels.FavoriteRelations{{ - SourcesID: source.Props["display_name"].(string), - Relations: graphModels.AnthrovePostRelationship{ - PostID: postRelation.Props["source_post_id"].(string), - Url: postRelation.Props["url"].(string), - }, - }}, - }) - - } - - } - - log.WithFields(log.Fields{ - "anthrove_user_fav_count": len(favoritePosts), - }).Trace("database: got al anthrove user favorites") - - return &graphModels.FavoriteList{Posts: favoritePosts}, nil - -} - -func GetUserTagNodeWitRelationToFavedPosts(ctx context.Context, driver neo4j.DriverWithContext, anthroveUserID models.AnthroveUserID) ([]graphModels.TagsWithFrequency, error) { - var userTags []graphModels.TagsWithFrequency - - query := ` - MATCH (u:User {user_id: $anthrove_user_id})-[:FAV]->(:AnthrovePost)-[:HAS]->(t:Tag) - RETURN t as tag, COUNT(t) AS frequency - ORDER BY frequency DESC - ` - params := map[string]any{ - "anthrove_user_id": anthroveUserID, - } - - result, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer) - if err != nil { - return nil, err - } - - if len(result.Records) == 0 { - return nil, nil - } - - for i := range result.Records { - record := result.Records[i] - - tag, _, err := neo4j.GetRecordValue[neo4j.Node](record, "tag") - if err != nil { - return nil, err - } - - frequency, _, err := neo4j.GetRecordValue[int64](record, "frequency") - if err != nil { - return nil, err - } - - userTags = append(userTags, graphModels.TagsWithFrequency{ - Frequency: frequency, - Tags: graphModels.AnthroveTag{ - Name: tag.Props["name"].(string), - Type: tag.Props["type"].(string), - }, - }) - - } - - log.WithFields(log.Fields{ - "tag_amount": len(userTags), - }).Trace("database: created tag node") - - return userTags, nil -} diff --git a/internal/postgres/post.go b/internal/postgres/post.go index 3ed43a5..d00c08a 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -6,14 +6,13 @@ import ( "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) func CreateAnthrovePostNode(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, anthroveRating models.Rating) error { - post := pgModels.Post{ - BaseModel: pgModels.BaseModel{ + post := models.Post{ + BaseModel: models.BaseModel{ ID: string(anthrovePostID), }, Rating: anthroveRating, @@ -41,8 +40,8 @@ func CheckIfAnthrovePostNodeExistsByAnthroveID(ctx context.Context, db *gorm.DB, } func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (*graphModels.AnthrovePost, bool, error) { - postRef := pgModels.PostReference{} - err := db.WithContext(ctx).Model(&pgModels.PostReference{}).Where("url = ?", sourceURL).First(&postRef).Error + postRef := models.PostReference{} + err := db.WithContext(ctx).Model(&models.PostReference{}).Where("url = ?", sourceURL).First(&postRef).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { @@ -51,7 +50,7 @@ func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, return nil, false, err } - var post pgModels.Post + var post models.Post err = db.WithContext(ctx).First(&post, "id = ?", postRef.PostID).Error if err != nil { @@ -76,7 +75,7 @@ func CheckIfAnthrovePostNodeExistsBySourceID(ctx context.Context, db *gorm.DB, s func executeCheckQuery(ctx context.Context, db *gorm.DB, query string, args ...interface{}) (bool, error) { var count int64 - err := db.WithContext(ctx).Model(&pgModels.Post{}).Where(query, args...).Count(&count).Error + err := db.WithContext(ctx).Model(&models.Post{}).Where(query, args...).Count(&count).Error if err != nil { return false, err } diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index a109fdb..969e66d 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -4,13 +4,12 @@ import ( "context" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error { - var source pgModels.Source + var source models.Source var err error // Find the source @@ -20,7 +19,7 @@ func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrov } // Establish the relationship - err = db.WithContext(ctx).Create(pgModels.PostReference{ + err = db.WithContext(ctx).Create(models.PostReference{ PostID: string(anthrovePostID), SourceID: source.ID, URL: anthrovePostRelationship.Url, @@ -39,7 +38,7 @@ func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrov } func EstablishUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error { - userFavorite := pgModels.UserFavorite{ + userFavorite := models.UserFavorite{ UserID: string(anthroveUserID), PostID: string(anthrovePostID), } @@ -59,7 +58,7 @@ func EstablishUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID mo func CheckUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) (bool, error) { var count int64 - err := db.WithContext(ctx).Model(&pgModels.UserFavorite{}).Where("user_id = ? AND post_id = ?", string(anthroveUserID), string(anthrovePostID)).Count(&count).Error + err := db.WithContext(ctx).Model(&models.UserFavorite{}).Where("user_id = ? AND post_id = ?", string(anthroveUserID), string(anthrovePostID)).Count(&count).Error if err != nil { return false, err } diff --git a/internal/postgres/relationships_test.go b/internal/postgres/relationships_test.go index 29b29ba..b96a5f3 100644 --- a/internal/postgres/relationships_test.go +++ b/internal/postgres/relationships_test.go @@ -3,7 +3,6 @@ package postgres import ( "context" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" "git.dragse.it/anthrove/otter-space-sdk/test" "gorm.io/gorm" "testing" @@ -26,7 +25,7 @@ func TestEstablishAnthrovePostToSourceLink(t *testing.T) { t.Fatal(err) } - source := &pgModels.Source{ + source := &models.Source{ DisplayName: "e621", Domain: "e621.net", Icon: "icon.e621.net", diff --git a/internal/postgres/source.go b/internal/postgres/source.go index 0e60a5e..5e4ecd5 100644 --- a/internal/postgres/source.go +++ b/internal/postgres/source.go @@ -3,20 +3,20 @@ package postgres import ( "context" "fmt" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) // CreateSourceNode creates a pgModels.Source -func CreateSourceNode(ctx context.Context, db *gorm.DB, anthroveSource *pgModels.Source) error { +func CreateSourceNode(ctx context.Context, db *gorm.DB, anthroveSource *models.Source) error { if anthroveSource.Domain == "" { return fmt.Errorf("anthroveSource domain is required") } - result := db.WithContext(ctx).Where(pgModels.Source{Domain: anthroveSource.Domain}).FirstOrCreate(anthroveSource) + result := db.WithContext(ctx).Where(models.Source{Domain: anthroveSource.Domain}).FirstOrCreate(anthroveSource) if result.Error != nil { return result.Error @@ -32,8 +32,8 @@ func CreateSourceNode(ctx context.Context, db *gorm.DB, anthroveSource *pgModels } // GetAllSourceNodes returns a list of all pgModels.Source -func GetAllSourceNodes(ctx context.Context, db *gorm.DB) ([]pgModels.Source, error) { - var sources []pgModels.Source +func GetAllSourceNodes(ctx context.Context, db *gorm.DB) ([]models.Source, error) { + var sources []models.Source result := db.WithContext(ctx).Find(&sources) @@ -49,8 +49,8 @@ func GetAllSourceNodes(ctx context.Context, db *gorm.DB) ([]pgModels.Source, err } // GetSourceNodesByURL returns the first source it finds based on the domain -func GetSourceNodesByURL(ctx context.Context, db *gorm.DB, domain string) (*pgModels.Source, error) { - var sources pgModels.Source +func GetSourceNodesByURL(ctx context.Context, db *gorm.DB, domain string) (*models.Source, error) { + var sources models.Source if domain == "" { return nil, fmt.Errorf("domain is required") diff --git a/internal/postgres/source_test.go b/internal/postgres/source_test.go index d0514c2..99fd7b8 100644 --- a/internal/postgres/source_test.go +++ b/internal/postgres/source_test.go @@ -2,7 +2,7 @@ package postgres import ( "context" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/test" "gorm.io/gorm" "testing" @@ -19,13 +19,13 @@ func TestCreateSourceNode(t *testing.T) { // Setup Test - validAnthroveSource := &pgModels.Source{ + validAnthroveSource := &models.Source{ DisplayName: "e621", Domain: "e621.net", Icon: "icon.e621.net", } - invalidAnthroveSource := &pgModels.Source{ + invalidAnthroveSource := &models.Source{ Domain: "", } @@ -33,7 +33,7 @@ func TestCreateSourceNode(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - anthroveSource *pgModels.Source + anthroveSource *models.Source } tests := []struct { name string @@ -88,7 +88,7 @@ func TestGetAllSourceNodes(t *testing.T) { // Setup Test - sources := []pgModels.Source{ + sources := []models.Source{ { DisplayName: "e621", Domain: "e621.net", @@ -121,7 +121,7 @@ func TestGetAllSourceNodes(t *testing.T) { tests := []struct { name string args args - want []pgModels.Source + want []models.Source wantErr bool }{ { @@ -159,7 +159,7 @@ func TestGetSourceNodesByURL(t *testing.T) { // Setup Test - source := &pgModels.Source{ + source := &models.Source{ DisplayName: "e621", Domain: "e621.net", Icon: "icon.e621.net", @@ -179,7 +179,7 @@ func TestGetSourceNodesByURL(t *testing.T) { tests := []struct { name string args args - want *pgModels.Source + want *models.Source wantErr bool }{ { @@ -227,7 +227,7 @@ func TestGetSourceNodesByURL(t *testing.T) { } } -func checkSourcesNode(got []pgModels.Source, want []pgModels.Source) bool { +func checkSourcesNode(got []models.Source, want []models.Source) bool { for i, source := range want { if source.DisplayName != got[i].DisplayName { return false @@ -244,7 +244,7 @@ func checkSourcesNode(got []pgModels.Source, want []pgModels.Source) bool { } -func checkSourceNode(got *pgModels.Source, want *pgModels.Source) bool { +func checkSourceNode(got *models.Source, want *models.Source) bool { if want == nil && got == nil { return true diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 4249069..124742e 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -4,12 +4,11 @@ import ( "context" "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) -func CreateTag(ctx context.Context, db *gorm.DB, tag *pgModels.Tag) error { +func CreateTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { resultTag := db.WithContext(ctx).Where(tag).Create(tag) @@ -25,7 +24,7 @@ func CreateTag(ctx context.Context, db *gorm.DB, tag *pgModels.Tag) error { return nil } -func CreateTagNodeWitRelation(ctx context.Context, db *gorm.DB, PostID models.AnthrovePostID, tag *pgModels.Tag) error { +func CreateTagNodeWitRelation(ctx context.Context, db *gorm.DB, PostID models.AnthrovePostID, tag *models.Tag) error { if PostID == "" { return fmt.Errorf("PostID is empty") @@ -37,8 +36,8 @@ func CreateTagNodeWitRelation(ctx context.Context, db *gorm.DB, PostID models.An return resultTag.Error } - pgPost := pgModels.Post{ - BaseModel: pgModels.BaseModel{ + pgPost := models.Post{ + BaseModel: models.BaseModel{ ID: string(PostID), }, } @@ -58,8 +57,8 @@ func CreateTagNodeWitRelation(ctx context.Context, db *gorm.DB, PostID models.An return nil } -func GetTags(ctx context.Context, db *gorm.DB) ([]pgModels.Tag, error) { - var tags []pgModels.Tag +func GetTags(ctx context.Context, db *gorm.DB) ([]models.Tag, error) { + var tags []models.Tag result := db.WithContext(ctx).Find(&tags) if result.Error != nil { return nil, result.Error diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index 347754e..c0b323a 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -3,7 +3,6 @@ package postgres import ( "context" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" "git.dragse.it/anthrove/otter-space-sdk/test" "gorm.io/gorm" "testing" @@ -25,7 +24,7 @@ func TestCreateTagNodeWitRelation(t *testing.T) { t.Fatal(err) } - tag := &pgModels.Tag{ + tag := &models.Tag{ Name: "JayTheFerret", Type: "artist", } @@ -35,7 +34,7 @@ func TestCreateTagNodeWitRelation(t *testing.T) { ctx context.Context db *gorm.DB PostID models.AnthrovePostID - tag *pgModels.Tag + tag *models.Tag } tests := []struct { name string @@ -103,7 +102,7 @@ func TestGetTags(t *testing.T) { // Setup Test - tags := []pgModels.Tag{ + tags := []models.Tag{ { Name: "JayTheFerret", Type: "artist", @@ -133,7 +132,7 @@ func TestGetTags(t *testing.T) { tests := []struct { name string args args - want []pgModels.Tag + want []models.Tag wantErr bool }{ { @@ -160,7 +159,7 @@ func TestGetTags(t *testing.T) { } } -func checkTag(got []pgModels.Tag, want []pgModels.Tag) bool { +func checkTag(got []models.Tag, want []models.Tag) bool { for i, tag := range want { if tag.Type != got[i].Type { return false diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 10b343c..2c9e56e 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -5,7 +5,6 @@ import ( "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) @@ -16,8 +15,8 @@ func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Anthrove return fmt.Errorf("anthroveUserID cannot be empty") } - user := pgModels.User{ - BaseModel: pgModels.BaseModel{ + user := models.User{ + BaseModel: models.BaseModel{ ID: string(anthroveUserID), }, } @@ -39,8 +38,8 @@ func CreateUserNodeWithSourceRelation(ctx context.Context, db *gorm.DB, anthrove return fmt.Errorf("anthroveUserID cannot be empty") } - user := pgModels.User{ - BaseModel: pgModels.BaseModel{ + user := models.User{ + BaseModel: models.BaseModel{ ID: string(anthroveUserID), }, } @@ -52,7 +51,7 @@ func CreateUserNodeWithSourceRelation(ctx context.Context, db *gorm.DB, anthrove return err } - source := pgModels.Source{ + source := models.Source{ Domain: sourceDomain, } @@ -63,7 +62,7 @@ func CreateUserNodeWithSourceRelation(ctx context.Context, db *gorm.DB, anthrove return err } - userSource := pgModels.UserSource{ + userSource := models.UserSource{ UserID: user.ID, SourceID: source.ID, AccountUsername: username, @@ -96,7 +95,7 @@ func GetUserFavoritesCount(ctx context.Context, db *gorm.DB, anthroveUserID mode } var count int64 - err := db.WithContext(ctx).Model(&pgModels.UserFavorite{}).Where("user_id = ?", string(anthroveUserID)).Count(&count).Error + err := db.WithContext(ctx).Model(&models.UserFavorite{}).Where("user_id = ?", string(anthroveUserID)).Count(&count).Error if err != nil { log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, @@ -113,10 +112,10 @@ func GetUserFavoritesCount(ctx context.Context, db *gorm.DB, anthroveUserID mode } func GetUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) (map[string]graphModels.AnthroveUserRelationship, error) { - var userSources []pgModels.UserSource + var userSources []models.UserSource userSourceMap := make(map[string]graphModels.AnthroveUserRelationship) - err := db.WithContext(ctx).Model(&pgModels.UserSource{}).Where("user_id = ?", string(anthroveUserID)).Find(&userSources).Error + err := db.WithContext(ctx).Model(&models.UserSource{}).Where("user_id = ?", string(anthroveUserID)).Find(&userSources).Error if err != nil { log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, @@ -125,8 +124,8 @@ func GetUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID models.A } for _, userSource := range userSources { - var source pgModels.Source - err = db.WithContext(ctx).Model(&pgModels.Source{}).Where("id = ?", userSource.SourceID).First(&source).Error + var source models.Source + err = db.WithContext(ctx).Model(&models.Source{}).Where("id = ?", userSource.SourceID).First(&source).Error if err != nil { log.WithFields(log.Fields{ "source_id": userSource.SourceID, @@ -157,10 +156,10 @@ func GetSpecifiedUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID return nil, fmt.Errorf("anthroveUserID or sourceDisplayName is empty") } - var userSources []pgModels.UserSource + var userSources []models.UserSource userSourceMap := make(map[string]graphModels.AnthroveUserRelationship) - err := db.WithContext(ctx).Model(&pgModels.UserSource{}).InnerJoins("Source", db.Where("display_name = ?", sourceDisplayName)).Where("user_id = ?", string(anthroveUserID)).First(&userSources).Error + err := db.WithContext(ctx).Model(&models.UserSource{}).InnerJoins("Source", db.Where("display_name = ?", sourceDisplayName)).Where("user_id = ?", string(anthroveUserID)).First(&userSources).Error if err != nil { log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, @@ -170,8 +169,8 @@ func GetSpecifiedUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID } for _, userSource := range userSources { - var source pgModels.Source - err = db.WithContext(ctx).Model(&pgModels.Source{}).Where("id = ?", userSource.SourceID).First(&source).Error + var source models.Source + err = db.WithContext(ctx).Model(&models.Source{}).Where("id = ?", userSource.SourceID).First(&source).Error if err != nil { log.WithFields(log.Fields{ "source_id": userSource.SourceID, @@ -204,8 +203,8 @@ func GetAnthroveUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Ant return nil, fmt.Errorf("anthroveUserID cannot be empty") } - var user pgModels.User - var userSources []pgModels.UserSource + var user models.User + var userSources []models.UserSource anthroveUser := &graphModels.AnthroveUser{ UserID: anthroveUserID, } @@ -218,7 +217,7 @@ func GetAnthroveUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Ant return nil, err } - err = db.WithContext(ctx).Model(&pgModels.UserSource{}).Where("user_id = ?", string(anthroveUserID)).Find(&userSources).Error + err = db.WithContext(ctx).Model(&models.UserSource{}).Where("user_id = ?", string(anthroveUserID)).Find(&userSources).Error if err != nil { log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, @@ -227,8 +226,8 @@ func GetAnthroveUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Ant } for _, userSource := range userSources { - var source pgModels.Source - err = db.WithContext(ctx).Model(&pgModels.Source{}).Where("id = ?", userSource.SourceID).First(&source).Error + var source models.Source + err = db.WithContext(ctx).Model(&models.Source{}).Where("id = ?", userSource.SourceID).First(&source).Error if err != nil { log.WithFields(log.Fields{ "source_id": userSource.SourceID, @@ -255,10 +254,10 @@ func GetAnthroveUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Ant } func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveUserID, error) { - var users []pgModels.User + var users []models.User var userIDs []models.AnthroveUserID - err := db.WithContext(ctx).Model(&pgModels.User{}).Find(&users).Error + err := db.WithContext(ctx).Model(&models.User{}).Find(&users).Error if err != nil { log.Error("database: failed to get all anthrove user IDs") return nil, err @@ -276,10 +275,10 @@ func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveU } func GetUserFavoriteNodeWithPagination(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, skip int, limit int) (*graphModels.FavoriteList, error) { - var userFavorites []pgModels.UserFavorite + var userFavorites []models.UserFavorite var favoritePosts []graphModels.FavoritePost - err := db.WithContext(ctx).Model(&pgModels.UserFavorite{}).Where("user_id = ?", string(anthroveUserID)).Offset(skip).Limit(limit).Find(&userFavorites).Error + err := db.WithContext(ctx).Model(&models.UserFavorite{}).Where("user_id = ?", string(anthroveUserID)).Offset(skip).Limit(limit).Find(&userFavorites).Error if err != nil { log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, @@ -290,8 +289,8 @@ func GetUserFavoriteNodeWithPagination(ctx context.Context, db *gorm.DB, anthrov } for _, userFavorite := range userFavorites { - var post pgModels.Post - err = db.WithContext(ctx).Model(&pgModels.Post{}).Where("id = ?", userFavorite.PostID).First(&post).Error + var post models.Post + err = db.WithContext(ctx).Model(&models.Post{}).Where("id = ?", userFavorite.PostID).First(&post).Error if err != nil { log.WithFields(log.Fields{ "post_id": userFavorite.PostID, @@ -316,7 +315,7 @@ func GetUserFavoriteNodeWithPagination(ctx context.Context, db *gorm.DB, anthrov } func GetUserTagNodeWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) ([]graphModels.TagsWithFrequency, error) { - var userFavorites []pgModels.UserFavorite + var userFavorites []models.UserFavorite err := db.WithContext(ctx).Where("user_id = ?", string(anthroveUserID)).Find(&userFavorites).Error if err != nil { log.WithFields(log.Fields{ @@ -330,7 +329,7 @@ func GetUserTagNodeWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, ant typeName string }]int) for _, userFavorite := range userFavorites { - var post pgModels.Post + var post models.Post err = db.WithContext(ctx).Preload("Tags").First(&post, "id = ?", userFavorite.PostID).Error if err != nil { log.WithFields(log.Fields{ diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index 531e13e..6beec7b 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -5,7 +5,6 @@ import ( "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" "git.dragse.it/anthrove/otter-space-sdk/test" "gorm.io/gorm" "reflect" @@ -73,7 +72,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { // Setup Test - source := &pgModels.Source{ + source := &models.Source{ DisplayName: "e621", Domain: "e621.net", Icon: "icon.e621.net", @@ -320,7 +319,7 @@ func TestGetSpecifiedUserSourceLink(t *testing.T) { defer container.Terminate(ctx) // Setup Test - source := &pgModels.Source{ + source := &models.Source{ DisplayName: "e621", Domain: "e621.net", } @@ -455,37 +454,37 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post1")), Rating: "safe", }, - }, + }, { AnthrovePost: graphModels.AnthrovePost{ PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post2")), Rating: "safe", }, - }, + }, { AnthrovePost: graphModels.AnthrovePost{ PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post3")), Rating: "explicit", }, - }, + }, { AnthrovePost: graphModels.AnthrovePost{ PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post4")), Rating: "explicit", }, - }, + }, { AnthrovePost: graphModels.AnthrovePost{ PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post5")), Rating: "questionable", }, - }, + }, { AnthrovePost: graphModels.AnthrovePost{ PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post6")), Rating: "safe", }, - }, + }, } expectedResult := &graphModels.FavoriteList{ Posts: expectedResultPostsGraph, @@ -502,31 +501,31 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { t.Fatal(err) } - expectedResultPostsPg := []pgModels.Post{ + expectedResultPostsPg := []models.Post{ { - BaseModel: pgModels.BaseModel{ID: "Post1"}, + BaseModel: models.BaseModel{ID: "Post1"}, Rating: "safe", - }, + }, { - BaseModel: pgModels.BaseModel{ID: "Post2"}, + BaseModel: models.BaseModel{ID: "Post2"}, Rating: "safe", - }, + }, { - BaseModel: pgModels.BaseModel{ID: "Post3"}, + BaseModel: models.BaseModel{ID: "Post3"}, Rating: "explicit", - }, + }, { - BaseModel: pgModels.BaseModel{ID: "Post4"}, + BaseModel: models.BaseModel{ID: "Post4"}, Rating: "explicit", - }, + }, { - BaseModel: pgModels.BaseModel{ID: "Post5"}, + BaseModel: models.BaseModel{ID: "Post5"}, Rating: "questionable", - }, + }, { - BaseModel: pgModels.BaseModel{ID: "Post6"}, + BaseModel: models.BaseModel{ID: "Post6"}, Rating: "safe", - }, + }, } for _, expectedResultPost := range expectedResultPostsPg { @@ -621,31 +620,31 @@ func TestGetUserFavoritesCount(t *testing.T) { t.Fatal(err) } - expectedResultPostsPg := []pgModels.Post{ + expectedResultPostsPg := []models.Post{ { - BaseModel: pgModels.BaseModel{ID: "Post1"}, + BaseModel: models.BaseModel{ID: "Post1"}, Rating: "safe", - }, + }, { - BaseModel: pgModels.BaseModel{ID: "Post2"}, + BaseModel: models.BaseModel{ID: "Post2"}, Rating: "safe", - }, + }, { - BaseModel: pgModels.BaseModel{ID: "Post3"}, + BaseModel: models.BaseModel{ID: "Post3"}, Rating: "explicit", - }, + }, { - BaseModel: pgModels.BaseModel{ID: "Post4"}, + BaseModel: models.BaseModel{ID: "Post4"}, Rating: "explicit", - }, + }, { - BaseModel: pgModels.BaseModel{ID: "Post5"}, + BaseModel: models.BaseModel{ID: "Post5"}, Rating: "questionable", - }, + }, { - BaseModel: pgModels.BaseModel{ID: "Post6"}, + BaseModel: models.BaseModel{ID: "Post6"}, Rating: "safe", - }, + }, } for _, expectedResultPost := range expectedResultPostsPg { @@ -727,7 +726,7 @@ func TestGetUserSourceLink(t *testing.T) { // Setup Test - esource := &pgModels.Source{ + esource := &models.Source{ DisplayName: "e621", Domain: "e621.net", } @@ -736,7 +735,7 @@ func TestGetUserSourceLink(t *testing.T) { t.Fatal(err) } - fasource := &pgModels.Source{ + fasource := &models.Source{ DisplayName: "fa", Domain: "fa.net", } @@ -823,10 +822,10 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { t.Fatal(err) } - posts := []pgModels.Post{ - {BaseModel: pgModels.BaseModel{ID: fmt.Sprintf("%-25s", "Post1")}, Rating: "safe"}, - {BaseModel: pgModels.BaseModel{ID: fmt.Sprintf("%-25s", "Post2")}, Rating: "safe"}, - {BaseModel: pgModels.BaseModel{ID: fmt.Sprintf("%-25s", "Post3")}, Rating: "explicit"}, + posts := []models.Post{ + {BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post1")}, Rating: "safe"}, + {BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post2")}, Rating: "safe"}, + {BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post3")}, Rating: "explicit"}, } for _, post := range posts { @@ -840,7 +839,7 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { } } - tags := []pgModels.Tag{ + tags := []models.Tag{ {Name: "JayTheFerret", Type: "artist"}, {Name: "Ferret", Type: "species"}, {Name: "Jay", Type: "character"}, diff --git a/internal/utils/modelConvert.go b/internal/utils/modelConvert.go deleted file mode 100644 index 29a4995..0000000 --- a/internal/utils/modelConvert.go +++ /dev/null @@ -1,60 +0,0 @@ -package utils - -import ( - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" -) - -// GraphConvertSource converts a graphModels.AnthroveSource to a pgModels.Source -func GraphConvertSource(graphSource *graphModels.AnthroveSource) *pgModels.Source { - pgSource := &pgModels.Source{ - DisplayName: graphSource.DisplayName, - Domain: graphSource.Domain, - Icon: graphSource.Icon, - } - return pgSource -} - -// PostgresConvertToAnthroveSource converts a pgModels.Source to a graphModels.AnthroveSource -func PostgresConvertToAnthroveSource(pgSource *pgModels.Source) *graphModels.AnthroveSource { - graphSource := &graphModels.AnthroveSource{ - DisplayName: pgSource.DisplayName, - Domain: pgSource.Domain, - Icon: pgSource.Icon, - } - - return graphSource -} - -// GraphConvertTag converts a graphModels.AnthroveTag to a pgModels.Tag -func GraphConvertTag(graphTag *graphModels.AnthroveTag) *pgModels.Tag { - pgTag := &pgModels.Tag{ - Name: graphTag.Name, - Type: models.TagType(graphTag.Type), - } - return pgTag -} - -// PostgresConvertToAnthroveTag converts a pgModels.Tag to a graphModels.AnthroveTag -func PostgresConvertToAnthroveTag(pgTag *pgModels.Tag) *graphModels.AnthroveTag { - graphTag := &graphModels.AnthroveTag{ - Name: pgTag.Name, - Type: string(pgTag.Type), - } - - return graphTag -} - -func ConvertToTagsWithFrequency(tags []pgModels.Tag) []graphModels.TagsWithFrequency { - var tagsWithFrequency []graphModels.TagsWithFrequency - for _, tag := range tags { - graphTag := PostgresConvertToAnthroveTag(&tag) - tagsWithFrequency = append(tagsWithFrequency, graphModels.TagsWithFrequency{ - Frequency: 0, - Tags: *graphTag, - }) - } - - return tagsWithFrequency -} diff --git a/pkg/database/database.go b/pkg/database/database.go index 307bc83..a6c908b 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -1,34 +1,8 @@ -// Package database provides a client for using the OtterSpace API. -// -// This package provides a client to interact with the OtterSpace API. It includes -// methods for all API endpoints, and convenience methods for common tasks. -// -// This is a simple usage example: -// -// package main -// -// import ( -// "context" -// "fmt" -// "git.dragse.it/anthrove/otter-space-sdk/pkg/models" -// "git.dragse.it/anthrove/otter-space-sdk/pkg/database" -// ) -// -// func main() { -// client := database.NewGraphConnection() -// err := client.Connect(context.Background(), "your-endpoint", "your-username", "your-password") -// if err != nil { -// fmt.Println(err) -// return -// } -// // further usage of the client... -// } package database import ( "context" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" ) // OtterSpace provides an interface for interacting with the OtterSpace API. @@ -45,23 +19,23 @@ type OtterSpace interface { // AddSource adds a new source to the OtterSpace database. // It returns an error if the operation fails. - AddSource(ctx context.Context, anthroveSource *graphModels.AnthroveSource) error + AddSource(ctx context.Context, anthroveSource *models.Source) error // AddPost adds a new post to the OtterSpace database. // It returns an error if the operation fails. - AddPost(ctx context.Context, anthrovePost *graphModels.AnthrovePost) error + AddPost(ctx context.Context, anthrovePost *models.Post) error // AddTagWithRelationToPost adds a new tag to the OtterSpace database and associates it with a post. // It returns an error if the operation fails. - AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *graphModels.AnthroveTag) error + AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error // LinkPostWithSource establishes a link between a post and a source in the OtterSpace database. // It returns an error if the operation fails. - LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error + LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *models.PostReference) error // LinkUserWithPost establishes a link between a user and a post in the OtterSpace database. // It returns an error if the operation fails. - LinkUserWithPost(ctx context.Context, anthroveUser *graphModels.AnthroveUser, anthrovePost *graphModels.AnthrovePost) error + LinkUserWithPost(ctx context.Context, anthroveUser *models.User, anthrovePost *models.Post) error // CheckUserPostLink checks if a link between a user and a post exists in the OtterSpace database. // It returns true if the link exists, false otherwise, and an error if the operation fails. @@ -69,15 +43,15 @@ type OtterSpace interface { // CheckPostNodeExistsByAnthroveID checks if a post node exists in the OtterSpace database by its Anthrove ID. // It returns the post if it exists, a boolean indicating whether the post was found, and an error if the operation fails. - CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *graphModels.AnthrovePost) (*graphModels.AnthrovePost, bool, error) + CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, bool, error) // CheckPostNodeExistsBySourceURL checks if a post node exists in the OtterSpace database by its source URL. // It returns the post if it exists, a boolean indicating whether the post was found, and an error if the operation fails. - CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*graphModels.AnthrovePost, bool, error) + CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*models.Post, bool, error) // CheckPostNodeExistsBySourceID checks if a post node exists in the OtterSpace database by its source ID. // It returns the post if it exists, a boolean indicating whether the post was found, and an error if the operation fails. - CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*graphModels.AnthrovePost, bool, error) + CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*models.Post, bool, error) // GetUserFavoriteCount retrieves the count of a user's favorite posts from the OtterSpace database. // It returns the count and an error if the operation fails. @@ -85,32 +59,32 @@ type OtterSpace interface { // GetUserSourceLinks retrieves the links between a user and sources in the OtterSpace database. // It returns a map of source domains to user-source relationships, and an error if the operation fails. - GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]graphModels.AnthroveUserRelationship, error) + GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) // GetSpecifiedUserSourceLink GetUserSourceLinks retrieves the links between a user and a specific source in the OtterSpace database. // It returns a map of source domains to user-source relationships, and an error if the operation fails. - GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]graphModels.AnthroveUserRelationship, error) + GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.UserSource, error) // GetAnthroveUser retrieves a user from the OtterSpace database by their ID. // It returns the user and an error if the operation fails. - GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*graphModels.AnthroveUser, error) + GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*models.User, error) // GetAllAnthroveUserIDs retrieves all user IDs from the OtterSpace database. // It returns a slice of user IDs and an error if the operation fails. GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) // GetUserFavoritePostsWithPagination gets all user favorites with relation and sources for the given user - GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*graphModels.FavoriteList, error) + GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) // GetUserTagsTroughFavedPosts returns a list of Tags that the user hs favorites through a post - GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]graphModels.TagsWithFrequency, error) + GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) // GetAllTags returns a list of Tags that the user hs favorites through a post - GetAllTags(ctx context.Context) ([]graphModels.TagsWithFrequency, error) + GetAllTags(ctx context.Context) ([]models.TagsWithFrequency, error) // GetAllSources returns a list of Sources in the database - GetAllSources(ctx context.Context) ([]graphModels.AnthroveSource, error) + GetAllSources(ctx context.Context) ([]models.Source, error) // GetSourceByURL returns the Source Node based on the URL - GetSourceByURL(ctx context.Context, sourceUrl string) (*graphModels.AnthroveSource, error) + GetSourceByURL(ctx context.Context, sourceUrl string) (*models.Source, error) } diff --git a/pkg/database/graph.go b/pkg/database/graph.go deleted file mode 100644 index 7fc5bf2..0000000 --- a/pkg/database/graph.go +++ /dev/null @@ -1,123 +0,0 @@ -package database - -import ( - "context" - "git.dragse.it/anthrove/otter-space-sdk/internal/graph" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" - "github.com/neo4j/neo4j-go-driver/v5/neo4j" - "github.com/neo4j/neo4j-go-driver/v5/neo4j/config" -) - -type graphConnection struct { - driver neo4j.DriverWithContext - graphDebug bool -} - -func NewGraphConnection(graphDebug bool) OtterSpace { - return &graphConnection{ - driver: nil, - graphDebug: graphDebug, - } -} - -func (g *graphConnection) Connect(ctx context.Context, endpoint string, username string, password string, _ string, _ int, _ string, _ string) error { - driver, err := neo4j.NewDriverWithContext(endpoint, neo4j.BasicAuth(username, password, ""), - logger(g.graphDebug)) - - if err != nil { - return err - } - err = driver.VerifyAuthentication(ctx, nil) - if err != nil { - return err - } - g.driver = driver - return nil -} - -func (g *graphConnection) AddUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error { - return graph.CreateUserNodeWithSourceRelation(ctx, g.driver, anthroveUserID, sourceDomain, userID, username) -} - -func (g *graphConnection) AddSource(ctx context.Context, anthroveSource *graphModels.AnthroveSource) error { - return graph.CreateSourceNode(ctx, g.driver, anthroveSource) -} - -func (g *graphConnection) AddPost(ctx context.Context, anthrovePost *graphModels.AnthrovePost) error { - return graph.CreateAnthrovePostNode(ctx, g.driver, anthrovePost) -} - -func (g *graphConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *graphModels.AnthroveTag) error { - return graph.CreateTagNodeWitRelation(ctx, g.driver, anthrovePostID, anthroveTag) -} - -func (g *graphConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error { - return graph.EstablishAnthrovePostToSourceLink(ctx, g.driver, anthrovePostID, anthroveSourceDomain, anthrovePostRelationship) -} - -func (g *graphConnection) LinkUserWithPost(ctx context.Context, anthroveUser *graphModels.AnthroveUser, anthrovePost *graphModels.AnthrovePost) error { - return graph.EstablishUserToPostLink(ctx, g.driver, anthroveUser, anthrovePost) -} - -func (g *graphConnection) CheckUserPostLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) { - return graph.CheckUserToPostLink(ctx, g.driver, anthroveUserID, sourcePostID, sourceUrl) -} - -func (g *graphConnection) CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *graphModels.AnthrovePost) (*graphModels.AnthrovePost, bool, error) { - return graph.CheckIfAnthrovePostNodeExistsByAnthroveID(ctx, g.driver, anthrovePost) -} - -func (g *graphConnection) CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*graphModels.AnthrovePost, bool, error) { - return graph.CheckIfAnthrovePostNodeExistsBySourceURl(ctx, g.driver, sourceUrl) -} - -func (g *graphConnection) CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*graphModels.AnthrovePost, bool, error) { - return graph.CheckIfAnthrovePostNodeExistsBySourceID(ctx, g.driver, sourcePostID) -} - -func (g *graphConnection) GetUserFavoriteCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) { - return graph.GetUserFavoritesCount(ctx, g.driver, anthroveUserID) -} - -func (g *graphConnection) GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]graphModels.AnthroveUserRelationship, error) { - return graph.GetUserSourceLink(ctx, g.driver, anthroveUserID) -} - -func (g *graphConnection) GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]graphModels.AnthroveUserRelationship, error) { - return graph.GetSpecifiedUserSourceLink(ctx, g.driver, anthroveUserID, sourceDisplayName) -} - -func (g *graphConnection) GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*graphModels.AnthroveUser, error) { - return graph.GetAnthroveUser(ctx, g.driver, anthroveUserID) -} - -func (g *graphConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) { - return graph.GetAllAnthroveUserIDs(ctx, g.driver) -} - -func (g *graphConnection) GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*graphModels.FavoriteList, error) { - return graph.GetUserFavoriteNodeWithPagination(ctx, g.driver, anthroveUserID, skip, limit) -} - -func (g *graphConnection) GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]graphModels.TagsWithFrequency, error) { - return graph.GetUserTagNodeWitRelationToFavedPosts(ctx, g.driver, anthroveUserID) -} - -func (g *graphConnection) GetAllTags(ctx context.Context) ([]graphModels.TagsWithFrequency, error) { - return graph.GetTags(ctx, g.driver) -} - -func (g *graphConnection) GetAllSources(ctx context.Context) ([]graphModels.AnthroveSource, error) { - return graph.GetAllSourceNodes(ctx, g.driver) -} - -func (g *graphConnection) GetSourceByURL(ctx context.Context, sourceUrl string) (*graphModels.AnthroveSource, error) { - return graph.GetSourceNodesByURL(ctx, g.driver, sourceUrl) -} - -func logger(graphDebug bool) func(config *config.Config) { - return func(config *config.Config) { - config.Log = graph.NewGraphLogger(graphDebug) - } -} diff --git a/pkg/database/migrations/001_inital_database.sql b/pkg/database/migrations/001_inital_database.sql index 70ae07a..749a337 100644 --- a/pkg/database/migrations/001_inital_database.sql +++ b/pkg/database/migrations/001_inital_database.sql @@ -89,10 +89,10 @@ CREATE TABLE "UserFavorites" CREATE TABLE "UserSource" ( - user_id TEXT REFERENCES "User" (id), - source_id TEXT REFERENCES "Source" (id), - account_username TEXT, - account_id TEXT, + user_id TEXT REFERENCES "User" (id), + source_id TEXT REFERENCES "Source" (id), + scrape_time_interval TEXT account_username TEXT, + account_id TEXT, PRIMARY KEY (user_id, source_id), UNIQUE (account_username, account_id) ); diff --git a/pkg/models/README.md b/pkg/models/README.md deleted file mode 100644 index af61315..0000000 --- a/pkg/models/README.md +++ /dev/null @@ -1,84 +0,0 @@ -# Postgres - -https://www.dbdiagram.io/d - -```` -Table User { - id string [primary key] - created_at timestamp -} - -Table Post { - id varchar(25) [primary key] - rating Rating - created_at timestamp -} - -Enum Rating { - safe - questionable - explicit -} - -Table Source { - id varchar(25) [primary key] - display_name text - domain text [not null, unique] -} - -Table Tag { - name text [primary key] - type TagType -} - -Enum TagType { - general - species - character - artist - lore - meta - invalid -} - -Table TagAlias { - name text [primary key] - tag_id text -} - -Table TagGroup { - name text [primary key] - tag_id text -} - -Table UserFavorites { - user_id text [primary key] - post_id text [primary key] - created_at timestamp -} - -Table UserSource { - user_id text [primary key] - source_id text [primary key] - account_username text - account_id text -} - -Table PostReference { - post_id text [primary key] - source_id text [primary key] - url text [not null, unique] - source_post_id text -} - -Ref: Tag.name > TagAlias.tag_id -Ref: Tag.name > TagGroup.tag_id -Ref: Tag.name <> Post.id -Ref: UserFavorites.user_id > User.id -Ref: UserFavorites.post_id > Post.id -Ref: UserSource.user_id > User.id -Ref: UserSource.source_id > Source.id -Ref: PostReference.post_id > Post.id -Ref: PostReference.source_id > Source.id - -```` \ No newline at end of file diff --git a/pkg/models/pgModels/orm.go b/pkg/models/orm.go similarity index 95% rename from pkg/models/pgModels/orm.go rename to pkg/models/orm.go index 4fd79bb..ff7bb64 100644 --- a/pkg/models/pgModels/orm.go +++ b/pkg/models/orm.go @@ -1,4 +1,4 @@ -package pgModels +package models import ( gonanoid "github.com/matoous/go-nanoid/v2" diff --git a/pkg/models/pgModels/userSource.go b/pkg/models/pgModels/userSource.go deleted file mode 100644 index 04371fe..0000000 --- a/pkg/models/pgModels/userSource.go +++ /dev/null @@ -1,13 +0,0 @@ -package pgModels - -type UserSource struct { - UserID string `gorm:"primaryKey"` - Source Source `gorm:"foreignKey:ID;references:SourceID"` - SourceID string `gorm:"primaryKey"` - AccountUsername string - AccountID string -} - -func (UserSource) TableName() string { - return "UserSource" -} diff --git a/pkg/models/pgModels/post.go b/pkg/models/post.go similarity index 65% rename from pkg/models/pgModels/post.go rename to pkg/models/post.go index d5ea588..bac8a50 100644 --- a/pkg/models/pgModels/post.go +++ b/pkg/models/post.go @@ -1,13 +1,9 @@ -package pgModels - -import ( - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" -) +package models // Post model type Post struct { BaseModel - Rating models.Rating `gorm:"type:enum('safe','questionable','explicit')"` + Rating Rating `gorm:"type:enum('safe','questionable','explicit')"` Tags []Tag `gorm:"many2many:post_tags;"` Favorites []UserFavorite `gorm:"foreignKey:PostID"` References []PostReference `gorm:"foreignKey:PostID"` diff --git a/pkg/models/pgModels/postReference.go b/pkg/models/postReference.go similarity index 95% rename from pkg/models/pgModels/postReference.go rename to pkg/models/postReference.go index 8ab7797..999e145 100644 --- a/pkg/models/pgModels/postReference.go +++ b/pkg/models/postReference.go @@ -1,4 +1,4 @@ -package pgModels +package models type PostReference struct { PostID string `gorm:"primaryKey"` diff --git a/pkg/models/pgModels/source.go b/pkg/models/source.go similarity index 95% rename from pkg/models/pgModels/source.go rename to pkg/models/source.go index 7159ea5..0860b81 100644 --- a/pkg/models/pgModels/source.go +++ b/pkg/models/source.go @@ -1,4 +1,4 @@ -package pgModels +package models // Source model type Source struct { diff --git a/pkg/models/pgModels/tag.go b/pkg/models/tag.go similarity index 53% rename from pkg/models/pgModels/tag.go rename to pkg/models/tag.go index 7538ac9..583cd78 100644 --- a/pkg/models/pgModels/tag.go +++ b/pkg/models/tag.go @@ -1,14 +1,12 @@ -package pgModels - -import "git.dragse.it/anthrove/otter-space-sdk/pkg/models" +package models // Tag models type Tag struct { - Name string `gorm:"primaryKey"` - Type models.TagType `gorm:"column:tag_type"` - Aliases []TagAlias `gorm:"foreignKey:TagID"` - Groups []TagGroup `gorm:"foreignKey:TagID"` - Posts []Post `gorm:"many2many:post_tags;"` + Name string `gorm:"primaryKey"` + Type TagType `gorm:"column:tag_type"` + Aliases []TagAlias `gorm:"foreignKey:TagID"` + Groups []TagGroup `gorm:"foreignKey:TagID"` + Posts []Post `gorm:"many2many:post_tags;"` } func (Tag) TableName() string { @@ -34,3 +32,8 @@ type TagGroup struct { func (TagGroup) TableName() string { return "TagGroup" } + +type TagsWithFrequency struct { + Frequency int64 `json:"frequency"` + Tags Tag `json:"tags"` +} diff --git a/pkg/models/pgModels/user.go b/pkg/models/user.go similarity index 92% rename from pkg/models/pgModels/user.go rename to pkg/models/user.go index 1120ae7..96dd70e 100644 --- a/pkg/models/pgModels/user.go +++ b/pkg/models/user.go @@ -1,4 +1,4 @@ -package pgModels +package models // User model type User struct { diff --git a/pkg/models/pgModels/userFavorite.go b/pkg/models/userFavorite.go similarity index 69% rename from pkg/models/pgModels/userFavorite.go rename to pkg/models/userFavorite.go index e01093f..1393c61 100644 --- a/pkg/models/pgModels/userFavorite.go +++ b/pkg/models/userFavorite.go @@ -1,4 +1,4 @@ -package pgModels +package models import "time" @@ -11,3 +11,7 @@ type UserFavorite struct { func (UserFavorite) TableName() string { return "UserFavorites" } + +type FavoriteList struct { + Posts []UserFavorite `json:"posts,omitempty"` +} diff --git a/pkg/models/userSource.go b/pkg/models/userSource.go new file mode 100644 index 0000000..97793d6 --- /dev/null +++ b/pkg/models/userSource.go @@ -0,0 +1,14 @@ +package models + +type UserSource struct { + UserID string `gorm:"primaryKey"` + Source Source `gorm:"foreignKey:ID;references:SourceID"` + SourceID string `gorm:"primaryKey"` + ScrapeTimeInterval string + AccountUsername string + AccountID string +} + +func (UserSource) TableName() string { + return "UserSource" +} -- 2.45.1 From b11cfbaa245401fb84baeee9bcac5d35307a029c Mon Sep 17 00:00:00 2001 From: soxx Date: Sat, 22 Jun 2024 22:07:36 +0200 Subject: [PATCH 059/124] refactor(postgres): removed old graph related code Signed-off-by: soxx --- pkg/database/postgres.go | 1 - pkg/models/graphModels/api.go | 20 -------------------- pkg/models/graphModels/post.go | 8 -------- pkg/models/graphModels/relationships.go | 12 ------------ pkg/models/graphModels/source.go | 7 ------- pkg/models/graphModels/tag.go | 6 ------ pkg/models/graphModels/user.go | 8 -------- 7 files changed, 62 deletions(-) delete mode 100644 pkg/models/graphModels/api.go delete mode 100644 pkg/models/graphModels/post.go delete mode 100644 pkg/models/graphModels/relationships.go delete mode 100644 pkg/models/graphModels/source.go delete mode 100644 pkg/models/graphModels/tag.go delete mode 100644 pkg/models/graphModels/user.go diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index ff4eb16..7025a97 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -71,7 +71,6 @@ func (p *postgresqlConnection) AddUserWithRelationToSource(ctx context.Context, } func (p *postgresqlConnection) AddSource(ctx context.Context, anthroveSource *graphModels.AnthroveSource) error { - source := utils.GraphConvertSource(anthroveSource) return postgres.CreateSourceNode(ctx, p.db, source) } diff --git a/pkg/models/graphModels/api.go b/pkg/models/graphModels/api.go deleted file mode 100644 index 7683097..0000000 --- a/pkg/models/graphModels/api.go +++ /dev/null @@ -1,20 +0,0 @@ -package graphModels - -type FavoriteRelations struct { - SourcesID string `json:"sources_id"` - Relations AnthrovePostRelationship `json:"relations"` -} - -type FavoritePost struct { - AnthrovePost AnthrovePost `json:"anthrove_post"` - Relations []FavoriteRelations `json:"relations"` -} - -type FavoriteList struct { - Posts []FavoritePost `json:"posts,omitempty"` -} - -type TagsWithFrequency struct { - Frequency int64 `json:"frequency"` - Tags AnthroveTag `json:"tags"` -} diff --git a/pkg/models/graphModels/post.go b/pkg/models/graphModels/post.go deleted file mode 100644 index 28caa38..0000000 --- a/pkg/models/graphModels/post.go +++ /dev/null @@ -1,8 +0,0 @@ -package graphModels - -import "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - -type AnthrovePost struct { - PostID models.AnthrovePostID `json:"post_id"` - Rating models.Rating `json:"rating"` -} diff --git a/pkg/models/graphModels/relationships.go b/pkg/models/graphModels/relationships.go deleted file mode 100644 index 639966f..0000000 --- a/pkg/models/graphModels/relationships.go +++ /dev/null @@ -1,12 +0,0 @@ -package graphModels - -type AnthroveUserRelationship struct { - UserID string `json:"user_id"` - Username string `json:"username"` - ScrapeTimeInterval string `json:"scrape_time_interval"` - Source AnthroveSource `json:"source"` -} -type AnthrovePostRelationship struct { - PostID string `json:"post_id"` - Url string `json:"url"` -} diff --git a/pkg/models/graphModels/source.go b/pkg/models/graphModels/source.go deleted file mode 100644 index 5e3795b..0000000 --- a/pkg/models/graphModels/source.go +++ /dev/null @@ -1,7 +0,0 @@ -package graphModels - -type AnthroveSource struct { - DisplayName string `json:"display_name"` - Domain string `json:"domain"` - Icon string `json:"icon"` -} diff --git a/pkg/models/graphModels/tag.go b/pkg/models/graphModels/tag.go deleted file mode 100644 index 699a1fc..0000000 --- a/pkg/models/graphModels/tag.go +++ /dev/null @@ -1,6 +0,0 @@ -package graphModels - -type AnthroveTag struct { - Name string `json:"name"` - Type string `json:"type"` -} diff --git a/pkg/models/graphModels/user.go b/pkg/models/graphModels/user.go deleted file mode 100644 index 3b74a51..0000000 --- a/pkg/models/graphModels/user.go +++ /dev/null @@ -1,8 +0,0 @@ -package graphModels - -import "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - -type AnthroveUser struct { - UserID models.AnthroveUserID `json:"user_id"` - Relationship []AnthroveUserRelationship `json:"relationship"` -} -- 2.45.1 From 2621eea00c58d549f0c6b1166ec1927bba3ada99 Mon Sep 17 00:00:00 2001 From: soxx Date: Sat, 22 Jun 2024 22:27:38 +0200 Subject: [PATCH 060/124] refactor(postgres): fixed implementation Signed-off-by: soxx --- internal/postgres/post.go | 21 +++++---- internal/postgres/relationships.go | 11 +++-- internal/postgres/tag.go | 2 +- pkg/database/database.go | 6 +-- pkg/database/postgres.go | 72 +++++++++++------------------- 5 files changed, 46 insertions(+), 66 deletions(-) diff --git a/internal/postgres/post.go b/internal/postgres/post.go index d00c08a..bf0fea4 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -5,17 +5,16 @@ import ( "errors" "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) -func CreateAnthrovePostNode(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, anthroveRating models.Rating) error { +func CreateAnthrovePostNode(ctx context.Context, db *gorm.DB, anthrovePost *models.Post) error { post := models.Post{ BaseModel: models.BaseModel{ - ID: string(anthrovePostID), + ID: string(anthrovePost.ID), }, - Rating: anthroveRating, + Rating: anthrovePost.Rating, } err := db.WithContext(ctx).Create(&post).Error @@ -24,14 +23,14 @@ func CreateAnthrovePostNode(ctx context.Context, db *gorm.DB, anthrovePostID mod } log.WithFields(log.Fields{ - "anthrove_post_id": anthrovePostID, - "anthrove_post_rating": anthroveRating, + "anthrove_post_id": anthrovePost.ID, + "anthrove_post_rating": anthrovePost.Rating, }).Trace("database: created anthrove post") return nil } -func CheckIfAnthrovePostNodeExistsByAnthroveID(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID) (bool, error) { +func GetPostByAnthroveID(ctx context.Context, db *gorm.DB, anthrovePostID string) (*models.Post, error) { if anthrovePostID == "" { return false, fmt.Errorf("anthrovePostID is required") } @@ -39,9 +38,9 @@ func CheckIfAnthrovePostNodeExistsByAnthroveID(ctx context.Context, db *gorm.DB, return executeCheckQuery(ctx, db, "id = ?", string(anthrovePostID)) } -func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (*graphModels.AnthrovePost, bool, error) { - postRef := models.PostReference{} - err := db.WithContext(ctx).Model(&models.PostReference{}).Where("url = ?", sourceURL).First(&postRef).Error +func GetPostBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (*models.Post, bool, error) { + var post models.Post + err := db.WithContext(ctx).Raw(`SELECT p.id AS id, p.rating as rating FROM "Post" AS p INNER JOIN "PostReference" AS pr ON p.id = pr.post_id AND pr.url = $1 LIMIT 1`, sourceURL).First(&post).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { @@ -68,7 +67,7 @@ func CheckIfAnthrovePostNodeExistsBySourceURL(ctx context.Context, db *gorm.DB, return &pgPost, true, nil } -func CheckIfAnthrovePostNodeExistsBySourceID(ctx context.Context, db *gorm.DB, sourceID string) (bool, error) { +func GetPostBySourceID(ctx context.Context, db *gorm.DB, sourceID string) (*models.Post, error) { return executeCheckQuery(ctx, db, "source_id = ?", sourceID) } diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index 969e66d..c6d020f 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -3,17 +3,16 @@ package postgres import ( "context" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) -func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error { +func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, sourceDomain string, anthrovePostRelationship *models.PostReference) error { var source models.Source var err error // Find the source - err = db.WithContext(ctx).Where("domain = ?", anthroveSourceDomain).First(&source).Error + err = db.WithContext(ctx).Where("domain = ?", sourceDomain).First(&source).Error if err != nil { return err } @@ -22,7 +21,7 @@ func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrov err = db.WithContext(ctx).Create(models.PostReference{ PostID: string(anthrovePostID), SourceID: source.ID, - URL: anthrovePostRelationship.Url, + URL: anthrovePostRelationship.URL, }).Error if err != nil { @@ -31,13 +30,13 @@ func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrov log.WithFields(log.Fields{ "anthrove_post_id": anthrovePostID, - "anthrove_source_domain": anthroveSourceDomain, + "anthrove_source_domain": sourceDomain, }).Trace("database: created anthrove post to source link") return nil } -func EstablishUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error { +func EstablishUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID string, anthrovePostID string) error { userFavorite := models.UserFavorite{ UserID: string(anthroveUserID), PostID: string(anthrovePostID), diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 124742e..03131e7 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -57,7 +57,7 @@ func CreateTagNodeWitRelation(ctx context.Context, db *gorm.DB, PostID models.An return nil } -func GetTags(ctx context.Context, db *gorm.DB) ([]models.Tag, error) { +func GetTags(ctx context.Context, db *gorm.DB) ([]models.TagsWithFrequency, error) { var tags []models.Tag result := db.WithContext(ctx).Find(&tags) if result.Error != nil { diff --git a/pkg/database/database.go b/pkg/database/database.go index a6c908b..dc95d91 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -43,15 +43,15 @@ type OtterSpace interface { // CheckPostNodeExistsByAnthroveID checks if a post node exists in the OtterSpace database by its Anthrove ID. // It returns the post if it exists, a boolean indicating whether the post was found, and an error if the operation fails. - CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, bool, error) + CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, error) // CheckPostNodeExistsBySourceURL checks if a post node exists in the OtterSpace database by its source URL. // It returns the post if it exists, a boolean indicating whether the post was found, and an error if the operation fails. - CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*models.Post, bool, error) + CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*models.Post, error) // CheckPostNodeExistsBySourceID checks if a post node exists in the OtterSpace database by its source ID. // It returns the post if it exists, a boolean indicating whether the post was found, and an error if the operation fails. - CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*models.Post, bool, error) + CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*models.Post, error) // GetUserFavoriteCount retrieves the count of a user's favorite posts from the OtterSpace database. // It returns the count and an error if the operation fails. diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 7025a97..d91f57a 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -6,9 +6,7 @@ import ( "embed" "fmt" "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" - "git.dragse.it/anthrove/otter-space-sdk/internal/utils" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" _ "github.com/lib/pq" migrate "github.com/rubenv/sql-migrate" log "github.com/sirupsen/logrus" @@ -70,61 +68,55 @@ func (p *postgresqlConnection) AddUserWithRelationToSource(ctx context.Context, return postgres.CreateUserNodeWithSourceRelation(ctx, p.db, anthroveUserID, sourceDomain, userID, userID) } -func (p *postgresqlConnection) AddSource(ctx context.Context, anthroveSource *graphModels.AnthroveSource) error { - return postgres.CreateSourceNode(ctx, p.db, source) +func (p *postgresqlConnection) AddSource(ctx context.Context, anthroveSource *models.Source) error { + return postgres.CreateSourceNode(ctx, p.db, anthroveSource) } -func (p *postgresqlConnection) AddPost(ctx context.Context, anthrovePost *graphModels.AnthrovePost) error { - return postgres.CreateAnthrovePostNode(ctx, p.db, anthrovePost.PostID, anthrovePost.Rating) +func (p *postgresqlConnection) AddPost(ctx context.Context, anthrovePost *models.Post) error { + return postgres.CreateAnthrovePostNode(ctx, p.db, anthrovePost) } -func (p *postgresqlConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *graphModels.AnthroveTag) error { - return postgres.CreateTagNodeWitRelation(ctx, p.db, anthrovePostID, utils.GraphConvertTag(anthroveTag)) +func (p *postgresqlConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error { + return postgres.CreateTagNodeWitRelation(ctx, p.db, anthrovePostID, anthroveTag) } -func (p *postgresqlConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error { - return postgres.EstablishAnthrovePostToSourceLink(ctx, p.db, anthrovePostID, anthroveSourceDomain, anthrovePostRelationship) +func (p *postgresqlConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain string, anthrovePostRelationship *models.PostReference) error { + return postgres.EstablishAnthrovePostToSourceLink(ctx, p.db, anthrovePostID, sourceDomain, anthrovePostRelationship) } -func (p *postgresqlConnection) LinkUserWithPost(ctx context.Context, anthroveUser *graphModels.AnthroveUser, anthrovePost *graphModels.AnthrovePost) error { - return postgres.EstablishUserToPostLink(ctx, p.db, anthroveUser.UserID, anthrovePost.PostID) +func (p *postgresqlConnection) LinkUserWithPost(ctx context.Context, anthroveUser *models.User, anthrovePost *models.Post) error { + return postgres.EstablishUserToPostLink(ctx, p.db, anthroveUser.ID, anthrovePost.ID) } func (p *postgresqlConnection) CheckUserPostLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) { return postgres.CheckUserToPostLink(ctx, p.db, anthroveUserID, models.AnthrovePostID(sourcePostID)) } -func (p *postgresqlConnection) CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *graphModels.AnthrovePost) (*graphModels.AnthrovePost, bool, error) { - exists, err := postgres.CheckIfAnthrovePostNodeExistsByAnthroveID(ctx, p.db, anthrovePost.PostID) - return anthrovePost, exists, err +func (p *postgresqlConnection) CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, error) { + return postgres.GetPostByAnthroveID(ctx, p.db, anthrovePost.ID) } -// CheckPostNodeExistsBySourceURL NOT WORKING! TODO! -func (p *postgresqlConnection) CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*graphModels.AnthrovePost, bool, error) { - post, exists, err := postgres.CheckIfAnthrovePostNodeExistsBySourceURL(ctx, p.db, sourceUrl) - return post, exists, err +func (p *postgresqlConnection) CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*models.Post, error) { + return postgres.GetPostBySourceURL(ctx, p.db, sourceUrl) } -// CheckPostNodeExistsBySourceID NOT WORKING! TODO! -func (p *postgresqlConnection) CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*graphModels.AnthrovePost, bool, error) { - var post graphModels.AnthrovePost - exists, err := postgres.CheckIfAnthrovePostNodeExistsBySourceID(ctx, p.db, sourcePostID) - return &post, exists, err +func (p *postgresqlConnection) CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*models.Post, error) { + return postgres.GetPostBySourceID(ctx, p.db, sourcePostID) } func (p *postgresqlConnection) GetUserFavoriteCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) { return postgres.GetUserFavoritesCount(ctx, p.db, anthroveUserID) } -func (p *postgresqlConnection) GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]graphModels.AnthroveUserRelationship, error) { +func (p *postgresqlConnection) GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) { return postgres.GetUserSourceLink(ctx, p.db, anthroveUserID) } -func (p *postgresqlConnection) GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]graphModels.AnthroveUserRelationship, error) { +func (p *postgresqlConnection) GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.UserSource, error) { return postgres.GetSpecifiedUserSourceLink(ctx, p.db, anthroveUserID, sourceDisplayName) } -func (p *postgresqlConnection) GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*graphModels.AnthroveUser, error) { +func (p *postgresqlConnection) GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*models.User, error) { return postgres.GetAnthroveUser(ctx, p.db, anthroveUserID) } @@ -132,34 +124,24 @@ func (p *postgresqlConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]mod return postgres.GetAllAnthroveUserIDs(ctx, p.db) } -func (p *postgresqlConnection) GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*graphModels.FavoriteList, error) { +func (p *postgresqlConnection) GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) { return postgres.GetUserFavoriteNodeWithPagination(ctx, p.db, anthroveUserID, skip, limit) } -func (p *postgresqlConnection) GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]graphModels.TagsWithFrequency, error) { +func (p *postgresqlConnection) GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { return postgres.GetUserTagNodeWitRelationToFavedPosts(ctx, p.db, anthroveUserID) } -func (p *postgresqlConnection) GetAllTags(ctx context.Context) ([]graphModels.TagsWithFrequency, error) { - tags, err := postgres.GetTags(ctx, p.db) - - return utils.ConvertToTagsWithFrequency(tags), err +func (p *postgresqlConnection) GetAllTags(ctx context.Context) ([]models.TagsWithFrequency, error) { + return postgres.GetTags(ctx, p.db) } -func (p *postgresqlConnection) GetAllSources(ctx context.Context) ([]graphModels.AnthroveSource, error) { - var anthroveSources []graphModels.AnthroveSource - source, err := postgres.GetAllSourceNodes(ctx, p.db) - - for _, v := range source { - anthroveSource := utils.PostgresConvertToAnthroveSource(&v) - anthroveSources = append(anthroveSources, *anthroveSource) - } - return nil, err +func (p *postgresqlConnection) GetAllSources(ctx context.Context) ([]models.Source, error) { + return postgres.GetAllSourceNodes(ctx, p.db) } -func (p *postgresqlConnection) GetSourceByURL(ctx context.Context, sourceUrl string) (*graphModels.AnthroveSource, error) { - source, err := postgres.GetSourceNodesByURL(ctx, p.db, sourceUrl) - return utils.PostgresConvertToAnthroveSource(source), err +func (p *postgresqlConnection) GetSourceByURL(ctx context.Context, sourceUrl string) (*models.Source, error) { + return postgres.GetSourceNodesByURL(ctx, p.db, sourceUrl) } func (p *postgresqlConnection) migrateDatabase(connectionString string) error { -- 2.45.1 From 78145fe02ab2d9451d7da6c056238660ea2305a3 Mon Sep 17 00:00:00 2001 From: soxx Date: Sat, 22 Jun 2024 22:28:29 +0200 Subject: [PATCH 061/124] refactor(postgres): removed old docs Signed-off-by: soxx --- pkg/database/database.go | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/pkg/database/database.go b/pkg/database/database.go index dc95d91..7977186 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -5,86 +5,46 @@ import ( "git.dragse.it/anthrove/otter-space-sdk/pkg/models" ) -// OtterSpace provides an interface for interacting with the OtterSpace API. -// It includes methods for connecting to the API, adding and linking users, posts, and sources, -// and retrieving information about users and posts. type OtterSpace interface { - // Connect sets up a connection to the OtterSpace API endpoint using the provided username and password. - // It returns an error if the connection cannot be established. Connect(ctx context.Context, endpoint string, username string, password string, database string, port int, ssl string, timezone string) error - // AddUserWithRelationToSource adds a new user to the OtterSpace database and associates them with a source. - // It returns the newly created user and an error if the operation fails. AddUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error - // AddSource adds a new source to the OtterSpace database. - // It returns an error if the operation fails. AddSource(ctx context.Context, anthroveSource *models.Source) error - // AddPost adds a new post to the OtterSpace database. - // It returns an error if the operation fails. AddPost(ctx context.Context, anthrovePost *models.Post) error - // AddTagWithRelationToPost adds a new tag to the OtterSpace database and associates it with a post. - // It returns an error if the operation fails. AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error - // LinkPostWithSource establishes a link between a post and a source in the OtterSpace database. - // It returns an error if the operation fails. LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *models.PostReference) error - // LinkUserWithPost establishes a link between a user and a post in the OtterSpace database. - // It returns an error if the operation fails. LinkUserWithPost(ctx context.Context, anthroveUser *models.User, anthrovePost *models.Post) error - // CheckUserPostLink checks if a link between a user and a post exists in the OtterSpace database. - // It returns true if the link exists, false otherwise, and an error if the operation fails. CheckUserPostLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) - // CheckPostNodeExistsByAnthroveID checks if a post node exists in the OtterSpace database by its Anthrove ID. - // It returns the post if it exists, a boolean indicating whether the post was found, and an error if the operation fails. CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, error) - // CheckPostNodeExistsBySourceURL checks if a post node exists in the OtterSpace database by its source URL. - // It returns the post if it exists, a boolean indicating whether the post was found, and an error if the operation fails. CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*models.Post, error) - // CheckPostNodeExistsBySourceID checks if a post node exists in the OtterSpace database by its source ID. - // It returns the post if it exists, a boolean indicating whether the post was found, and an error if the operation fails. CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*models.Post, error) - // GetUserFavoriteCount retrieves the count of a user's favorite posts from the OtterSpace database. - // It returns the count and an error if the operation fails. GetUserFavoriteCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) - // GetUserSourceLinks retrieves the links between a user and sources in the OtterSpace database. - // It returns a map of source domains to user-source relationships, and an error if the operation fails. GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) - // GetSpecifiedUserSourceLink GetUserSourceLinks retrieves the links between a user and a specific source in the OtterSpace database. - // It returns a map of source domains to user-source relationships, and an error if the operation fails. GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.UserSource, error) - // GetAnthroveUser retrieves a user from the OtterSpace database by their ID. - // It returns the user and an error if the operation fails. GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*models.User, error) - // GetAllAnthroveUserIDs retrieves all user IDs from the OtterSpace database. - // It returns a slice of user IDs and an error if the operation fails. GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) - // GetUserFavoritePostsWithPagination gets all user favorites with relation and sources for the given user GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) - // GetUserTagsTroughFavedPosts returns a list of Tags that the user hs favorites through a post GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) - // GetAllTags returns a list of Tags that the user hs favorites through a post GetAllTags(ctx context.Context) ([]models.TagsWithFrequency, error) - // GetAllSources returns a list of Sources in the database GetAllSources(ctx context.Context) ([]models.Source, error) - // GetSourceByURL returns the Source Node based on the URL GetSourceByURL(ctx context.Context, sourceUrl string) (*models.Source, error) } -- 2.45.1 From 55296d9a95b6ca4de03f12e99e2a215dc43ed6e2 Mon Sep 17 00:00:00 2001 From: soxx Date: Sat, 22 Jun 2024 22:30:03 +0200 Subject: [PATCH 062/124] refactor(postgres): renamed functions to be more clear Signed-off-by: soxx --- pkg/database/database.go | 6 +++--- pkg/database/postgres.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/database/database.go b/pkg/database/database.go index 7977186..bc31c17 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -22,11 +22,11 @@ type OtterSpace interface { CheckUserPostLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) - CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, error) + GetPostByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, error) - CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*models.Post, error) + GetPostBySourceURL(ctx context.Context, sourceUrl string) (*models.Post, error) - CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*models.Post, error) + GetPostBySourceID(ctx context.Context, sourcePostID string) (*models.Post, error) GetUserFavoriteCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index d91f57a..f4a2750 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -92,15 +92,15 @@ func (p *postgresqlConnection) CheckUserPostLink(ctx context.Context, anthroveUs return postgres.CheckUserToPostLink(ctx, p.db, anthroveUserID, models.AnthrovePostID(sourcePostID)) } -func (p *postgresqlConnection) CheckPostNodeExistsByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, error) { +func (p *postgresqlConnection) GetPostByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, error) { return postgres.GetPostByAnthroveID(ctx, p.db, anthrovePost.ID) } -func (p *postgresqlConnection) CheckPostNodeExistsBySourceURL(ctx context.Context, sourceUrl string) (*models.Post, error) { +func (p *postgresqlConnection) GetPostBySourceURL(ctx context.Context, sourceUrl string) (*models.Post, error) { return postgres.GetPostBySourceURL(ctx, p.db, sourceUrl) } -func (p *postgresqlConnection) CheckPostNodeExistsBySourceID(ctx context.Context, sourcePostID string) (*models.Post, error) { +func (p *postgresqlConnection) GetPostBySourceID(ctx context.Context, sourcePostID string) (*models.Post, error) { return postgres.GetPostBySourceID(ctx, p.db, sourcePostID) } -- 2.45.1 From b28891f3835b82e603428380ba934f37ed2e2a24 Mon Sep 17 00:00:00 2001 From: soxx Date: Sat, 22 Jun 2024 23:23:23 +0200 Subject: [PATCH 063/124] refactor(postgres): fixed any IDE errors Signed-off-by: soxx --- internal/postgres/user.go | 108 ++++++++------------------------- internal/postgres/user_test.go | 6 +- pkg/database/database.go | 22 ++++++- pkg/database/postgres.go | 6 +- pkg/models/userFavorite.go | 2 +- 5 files changed, 50 insertions(+), 94 deletions(-) diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 2c9e56e..c7b0586 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) @@ -111,9 +110,9 @@ func GetUserFavoritesCount(ctx context.Context, db *gorm.DB, anthroveUserID mode return count, nil } -func GetUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) (map[string]graphModels.AnthroveUserRelationship, error) { +func GetUserSourceLinks(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) { var userSources []models.UserSource - userSourceMap := make(map[string]graphModels.AnthroveUserRelationship) + userSourceMap := make(map[string]models.UserSource) err := db.WithContext(ctx).Model(&models.UserSource{}).Where("user_id = ?", string(anthroveUserID)).Find(&userSources).Error if err != nil { @@ -133,10 +132,10 @@ func GetUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID models.A return nil, err } - userSourceMap[source.DisplayName] = graphModels.AnthroveUserRelationship{ - UserID: userSource.AccountID, - Username: userSource.AccountUsername, - Source: graphModels.AnthroveSource{ + userSourceMap[source.DisplayName] = models.UserSource{ + UserID: userSource.AccountID, + AccountUsername: userSource.AccountUsername, + Source: models.Source{ DisplayName: source.DisplayName, Domain: source.Domain, Icon: source.Icon, @@ -151,13 +150,13 @@ func GetUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID models.A return userSourceMap, nil } -func GetSpecifiedUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]graphModels.AnthroveUserRelationship, error) { +func GetSpecifiedUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.UserSource, error) { if anthroveUserID == "" || sourceDisplayName == "" { return nil, fmt.Errorf("anthroveUserID or sourceDisplayName is empty") } var userSources []models.UserSource - userSourceMap := make(map[string]graphModels.AnthroveUserRelationship) + userSourceMap := make(map[string]models.UserSource) err := db.WithContext(ctx).Model(&models.UserSource{}).InnerJoins("Source", db.Where("display_name = ?", sourceDisplayName)).Where("user_id = ?", string(anthroveUserID)).First(&userSources).Error if err != nil { @@ -178,10 +177,10 @@ func GetSpecifiedUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID return nil, err } - userSourceMap[source.DisplayName] = graphModels.AnthroveUserRelationship{ - UserID: userSource.AccountID, - Username: userSource.AccountUsername, - Source: graphModels.AnthroveSource{ + userSourceMap[source.DisplayName] = models.UserSource{ + UserID: userSource.AccountID, + AccountUsername: userSource.AccountUsername, + Source: models.Source{ DisplayName: source.DisplayName, Domain: source.Domain, Icon: source.Icon, @@ -197,62 +196,6 @@ func GetSpecifiedUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID return userSourceMap, nil } -func GetAnthroveUser(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) (*graphModels.AnthroveUser, error) { - - if anthroveUserID == "" { - return nil, fmt.Errorf("anthroveUserID cannot be empty") - } - - var user models.User - var userSources []models.UserSource - anthroveUser := &graphModels.AnthroveUser{ - UserID: anthroveUserID, - } - - err := db.WithContext(ctx).First(&user, "id = ?", string(anthroveUserID)).Error - if err != nil { - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - }).Error("database: failed to get user") - return nil, err - } - - err = db.WithContext(ctx).Model(&models.UserSource{}).Where("user_id = ?", string(anthroveUserID)).Find(&userSources).Error - if err != nil { - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - }).Error("database: failed to get user sources") - return nil, err - } - - for _, userSource := range userSources { - var source models.Source - err = db.WithContext(ctx).Model(&models.Source{}).Where("id = ?", userSource.SourceID).First(&source).Error - if err != nil { - log.WithFields(log.Fields{ - "source_id": userSource.SourceID, - }).Error("database: failed to get source") - return nil, err - } - - anthroveUser.Relationship = append(anthroveUser.Relationship, graphModels.AnthroveUserRelationship{ - UserID: userSource.AccountID, - Username: userSource.AccountUsername, - Source: graphModels.AnthroveSource{ - DisplayName: source.DisplayName, - Domain: source.Domain, - Icon: source.Icon, - }, - }) - } - - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - }).Trace("database: got anthrove user") - - return anthroveUser, nil -} - func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveUserID, error) { var users []models.User var userIDs []models.AnthroveUserID @@ -274,9 +217,9 @@ func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveU return userIDs, nil } -func GetUserFavoriteNodeWithPagination(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, skip int, limit int) (*graphModels.FavoriteList, error) { +func GetUserFavoriteNodeWithPagination(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) { var userFavorites []models.UserFavorite - var favoritePosts []graphModels.FavoritePost + var favoritePosts []models.Post err := db.WithContext(ctx).Model(&models.UserFavorite{}).Where("user_id = ?", string(anthroveUserID)).Offset(skip).Limit(limit).Find(&userFavorites).Error if err != nil { @@ -298,12 +241,11 @@ func GetUserFavoriteNodeWithPagination(ctx context.Context, db *gorm.DB, anthrov return nil, err } - favoritePosts = append(favoritePosts, graphModels.FavoritePost{ - AnthrovePost: graphModels.AnthrovePost{ - PostID: models.AnthrovePostID(post.ID), - Rating: post.Rating, - }, - }) + favoritePosts = append(favoritePosts, + models.Post{ + BaseModel: models.BaseModel{ID: post.ID}, + Rating: post.Rating, + }) } log.WithFields(log.Fields{ @@ -311,10 +253,10 @@ func GetUserFavoriteNodeWithPagination(ctx context.Context, db *gorm.DB, anthrov "anthrove_user_fav_count": len(favoritePosts), }).Trace("database: got all anthrove user favorites") - return &graphModels.FavoriteList{Posts: favoritePosts}, nil + return &models.FavoriteList{Posts: favoritePosts}, nil } -func GetUserTagNodeWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) ([]graphModels.TagsWithFrequency, error) { +func GetUserTagNodeWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { var userFavorites []models.UserFavorite err := db.WithContext(ctx).Where("user_id = ?", string(anthroveUserID)).Find(&userFavorites).Error if err != nil { @@ -346,13 +288,13 @@ func GetUserTagNodeWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, ant } } - var tagsWithFrequency []graphModels.TagsWithFrequency + var tagsWithFrequency []models.TagsWithFrequency for data, frequency := range tagFrequency { - tagsWithFrequency = append(tagsWithFrequency, graphModels.TagsWithFrequency{ + tagsWithFrequency = append(tagsWithFrequency, models.TagsWithFrequency{ Frequency: int64(frequency), - Tags: graphModels.AnthroveTag{ + Tags: models.Tag{ Name: data.name, - Type: data.typeName, + Type: models.TagType(data.typeName), }, }) } diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index 6beec7b..b0742c5 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -795,13 +795,13 @@ func TestGetUserSourceLink(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := GetUserSourceLink(tt.args.ctx, tt.args.db, tt.args.anthroveUserID) + got, err := GetUserSourceLinks(tt.args.ctx, tt.args.db, tt.args.anthroveUserID) if (err != nil) != tt.wantErr { - t.Errorf("GetUserSourceLink() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetUserSourceLinks() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetUserSourceLink() got = %v, want %v", got, tt.want) + t.Errorf("GetUserSourceLinks() got = %v, want %v", got, tt.want) } }) } diff --git a/pkg/database/database.go b/pkg/database/database.go index bc31c17..76269bf 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -6,45 +6,63 @@ import ( ) type OtterSpace interface { + // Connect establishes a connection to the database. Connect(ctx context.Context, endpoint string, username string, password string, database string, port int, ssl string, timezone string) error + // AddUserWithRelationToSource adds a user with a relation to a source. AddUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error + // AddSource adds a new source to the database. AddSource(ctx context.Context, anthroveSource *models.Source) error + // AddPost adds a new post to the database. AddPost(ctx context.Context, anthrovePost *models.Post) error + // AddTagWithRelationToPost adds a tag with a relation to a post. AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error + // LinkPostWithSource links a post with a source. LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *models.PostReference) error + // LinkUserWithPost links a user with a post. LinkUserWithPost(ctx context.Context, anthroveUser *models.User, anthrovePost *models.Post) error + // CheckUserPostLink checks if a user-post link exists. CheckUserPostLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) + // GetPostByAnthroveID retrieves a post by its Anthrove ID. GetPostByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, error) + // GetPostBySourceURL retrieves a post by its source URL. GetPostBySourceURL(ctx context.Context, sourceUrl string) (*models.Post, error) + // GetPostBySourceID retrieves a post by its source ID. GetPostBySourceID(ctx context.Context, sourcePostID string) (*models.Post, error) + // GetUserFavoriteCount retrieves the count of a user's favorites. GetUserFavoriteCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) + // GetUserSourceLinks retrieves the source links of a user. GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) + // GetSpecifiedUserSourceLink retrieves a specified source link of a user. GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.UserSource, error) - GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*models.User, error) - + // GetAllAnthroveUserIDs retrieves all Anthrove user IDs. GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) + // GetUserFavoritePostsWithPagination retrieves a user's favorite posts with pagination. GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) + // GetUserTagsTroughFavedPosts retrieves a user's tags through their favorited posts. GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) + // GetAllTags retrieves all tags. GetAllTags(ctx context.Context) ([]models.TagsWithFrequency, error) + // GetAllSources retrieves all sources. GetAllSources(ctx context.Context) ([]models.Source, error) + // GetSourceByURL retrieves a source by its URL. GetSourceByURL(ctx context.Context, sourceUrl string) (*models.Source, error) } diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index f4a2750..ac996c0 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -109,17 +109,13 @@ func (p *postgresqlConnection) GetUserFavoriteCount(ctx context.Context, anthrov } func (p *postgresqlConnection) GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) { - return postgres.GetUserSourceLink(ctx, p.db, anthroveUserID) + return postgres.GetUserSourceLinks(ctx, p.db, anthroveUserID) } func (p *postgresqlConnection) GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.UserSource, error) { return postgres.GetSpecifiedUserSourceLink(ctx, p.db, anthroveUserID, sourceDisplayName) } -func (p *postgresqlConnection) GetAnthroveUser(ctx context.Context, anthroveUserID models.AnthroveUserID) (*models.User, error) { - return postgres.GetAnthroveUser(ctx, p.db, anthroveUserID) -} - func (p *postgresqlConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) { return postgres.GetAllAnthroveUserIDs(ctx, p.db) } diff --git a/pkg/models/userFavorite.go b/pkg/models/userFavorite.go index 1393c61..8ccd106 100644 --- a/pkg/models/userFavorite.go +++ b/pkg/models/userFavorite.go @@ -13,5 +13,5 @@ func (UserFavorite) TableName() string { } type FavoriteList struct { - Posts []UserFavorite `json:"posts,omitempty"` + Posts []Post `json:"posts,omitempty"` } -- 2.45.1 From 9471941e025bc268f29fe648236e59ce227b57b0 Mon Sep 17 00:00:00 2001 From: soxx Date: Sat, 22 Jun 2024 23:25:06 +0200 Subject: [PATCH 064/124] refactor(postgres): fixed any IDE errors Signed-off-by: soxx --- internal/postgres/tag.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 03131e7..124742e 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -57,7 +57,7 @@ func CreateTagNodeWitRelation(ctx context.Context, db *gorm.DB, PostID models.An return nil } -func GetTags(ctx context.Context, db *gorm.DB) ([]models.TagsWithFrequency, error) { +func GetTags(ctx context.Context, db *gorm.DB) ([]models.Tag, error) { var tags []models.Tag result := db.WithContext(ctx).Find(&tags) if result.Error != nil { -- 2.45.1 From bb7cb23c2a468253661dc99c428d6a75fde7cbd1 Mon Sep 17 00:00:00 2001 From: soxx Date: Sat, 22 Jun 2024 23:25:28 +0200 Subject: [PATCH 065/124] refactor(postgres): Refactor post retrieval functions and remove unnecessary code in tag and user creation Signed-off-by: soxx --- internal/postgres/post.go | 56 +++++++++++++-------------------------- internal/postgres/tag.go | 6 ----- internal/postgres/user.go | 15 +---------- pkg/models/userSource.go | 1 + 4 files changed, 21 insertions(+), 57 deletions(-) diff --git a/internal/postgres/post.go b/internal/postgres/post.go index bf0fea4..32ee5af 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -32,60 +32,42 @@ func CreateAnthrovePostNode(ctx context.Context, db *gorm.DB, anthrovePost *mode func GetPostByAnthroveID(ctx context.Context, db *gorm.DB, anthrovePostID string) (*models.Post, error) { if anthrovePostID == "" { - return false, fmt.Errorf("anthrovePostID is required") + return nil, fmt.Errorf("anthrovePostID is required") } - return executeCheckQuery(ctx, db, "id = ?", string(anthrovePostID)) + var post models.Post + err := db.WithContext(ctx).First(&post, "id = ?", anthrovePostID).Error + if err != nil { + return nil, err + } + + return &post, nil } -func GetPostBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (*models.Post, bool, error) { +func GetPostBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (*models.Post, error) { var post models.Post err := db.WithContext(ctx).Raw(`SELECT p.id AS id, p.rating as rating FROM "Post" AS p INNER JOIN "PostReference" AS pr ON p.id = pr.post_id AND pr.url = $1 LIMIT 1`, sourceURL).First(&post).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return nil, false, nil + return nil, nil } - return nil, false, err + return nil, err } - var post models.Post - err = db.WithContext(ctx).First(&post, "id = ?", postRef.PostID).Error - - if err != nil { - return nil, false, err - } - - pgPost := graphModels.AnthrovePost{ - PostID: models.AnthrovePostID(post.ID), - Rating: post.Rating, - } - - //TODO Now test it! :D - // Naaa - // D: - return &pgPost, true, nil + return &post, nil } func GetPostBySourceID(ctx context.Context, db *gorm.DB, sourceID string) (*models.Post, error) { - return executeCheckQuery(ctx, db, "source_id = ?", sourceID) -} + var post models.Post + err := db.WithContext(ctx).Raw(`SELECT p.id AS id, p.rating as rating FROM "Post" AS p INNER JOIN "PostReference" AS pr ON p.id = pr.post_id AND pr.source_id = $1 LIMIT 1`, sourceID).First(&post).Error -func executeCheckQuery(ctx context.Context, db *gorm.DB, query string, args ...interface{}) (bool, error) { - var count int64 - - err := db.WithContext(ctx).Model(&models.Post{}).Where(query, args...).Count(&count).Error if err != nil { - return false, err + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, nil + } + return nil, err } - exists := count > 0 - - log.WithFields(log.Fields{ - "query": query, - "args": args, - "exists": exists, - }).Trace("database: executed check query") - - return exists, nil + return &post, nil } diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 124742e..40e0f68 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -30,12 +30,6 @@ func CreateTagNodeWitRelation(ctx context.Context, db *gorm.DB, PostID models.An return fmt.Errorf("PostID is empty") } - resultTag := db.WithContext(ctx).Where(tag).FirstOrCreate(tag) - - if resultTag.Error != nil { - return resultTag.Error - } - pgPost := models.Post{ BaseModel: models.BaseModel{ ID: string(PostID), diff --git a/internal/postgres/user.go b/internal/postgres/user.go index c7b0586..8afd07f 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -37,19 +37,6 @@ func CreateUserNodeWithSourceRelation(ctx context.Context, db *gorm.DB, anthrove return fmt.Errorf("anthroveUserID cannot be empty") } - user := models.User{ - BaseModel: models.BaseModel{ - ID: string(anthroveUserID), - }, - } - - if err := db.WithContext(ctx).FirstOrCreate(&user).Error; err != nil { - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - }).Error("database: failed to find or create user") - return err - } - source := models.Source{ Domain: sourceDomain, } @@ -62,7 +49,7 @@ func CreateUserNodeWithSourceRelation(ctx context.Context, db *gorm.DB, anthrove } userSource := models.UserSource{ - UserID: user.ID, + User: models.User{BaseModel: models.BaseModel{ID: string(anthroveUserID)}}, SourceID: source.ID, AccountUsername: username, AccountID: userID, diff --git a/pkg/models/userSource.go b/pkg/models/userSource.go index 97793d6..59788a1 100644 --- a/pkg/models/userSource.go +++ b/pkg/models/userSource.go @@ -1,6 +1,7 @@ package models type UserSource struct { + User User `gorm:"foreignKey:ID;references:UserID"` UserID string `gorm:"primaryKey"` Source Source `gorm:"foreignKey:ID;references:SourceID"` SourceID string `gorm:"primaryKey"` -- 2.45.1 From 7842976f4b4a3cb7eda14aca5c6d22f207da269c Mon Sep 17 00:00:00 2001 From: soxx Date: Sun, 23 Jun 2024 01:18:23 +0200 Subject: [PATCH 066/124] test(postgres): fixed the tests & also squashed some bugs Signed-off-by: soxx --- internal/postgres/post.go | 11 +- internal/postgres/post_test.go | 312 +++++++++++++++--- internal/postgres/relationships.go | 8 +- internal/postgres/relationships_test.go | 272 ++++++++------- internal/postgres/source_test.go | 10 +- internal/postgres/tag.go | 8 +- internal/postgres/tag_test.go | 20 +- internal/postgres/user.go | 23 +- internal/postgres/user_test.go | 295 +++++------------ .../migrations/001_inital_database.sql | 3 +- pkg/database/postgres.go | 2 +- 11 files changed, 556 insertions(+), 408 deletions(-) diff --git a/internal/postgres/post.go b/internal/postgres/post.go index 32ee5af..079be3d 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -9,15 +9,8 @@ import ( "gorm.io/gorm" ) -func CreateAnthrovePostNode(ctx context.Context, db *gorm.DB, anthrovePost *models.Post) error { - post := models.Post{ - BaseModel: models.BaseModel{ - ID: string(anthrovePost.ID), - }, - Rating: anthrovePost.Rating, - } - - err := db.WithContext(ctx).Create(&post).Error +func CreatePost(ctx context.Context, db *gorm.DB, anthrovePost *models.Post) error { + err := db.WithContext(ctx).Create(&anthrovePost).Error if err != nil { return err } diff --git a/internal/postgres/post_test.go b/internal/postgres/post_test.go index 20444e7..87d2690 100644 --- a/internal/postgres/post_test.go +++ b/internal/postgres/post_test.go @@ -2,6 +2,7 @@ package postgres import ( "context" + "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/test" _ "github.com/lib/pq" @@ -19,11 +20,24 @@ func TestCreateAnthrovePostNode(t *testing.T) { } defer container.Terminate(ctx) + // Setup Tests + + validPost := &models.Post{ + BaseModel: models.BaseModel{ + ID: fmt.Sprintf("%025s", "1"), + }, + Rating: "safe", + } + + invalidPost := &models.Post{ + Rating: "error", + } + + // Test type args struct { - ctx context.Context - db *gorm.DB - anthrovePostID models.AnthrovePostID - anthroveRating models.Rating + ctx context.Context + db *gorm.DB + anthrovePost *models.Post } tests := []struct { name string @@ -33,34 +47,32 @@ func TestCreateAnthrovePostNode(t *testing.T) { { name: "Test 1: Valid AnthrovePostID and Rating", args: args{ - ctx: context.Background(), - db: gormDB, - anthrovePostID: "1234", - anthroveRating: models.Rating("safe"), + ctx: context.Background(), + db: gormDB, + anthrovePost: validPost, }, wantErr: false, }, { - name: "Test 2: Invalid AnthrovePostID and Rating", + name: "Test 2: Invalid Rating", args: args{ - ctx: context.Background(), - db: gormDB, - anthrovePostID: "", - anthroveRating: "a4dsa4d", + ctx: context.Background(), + db: gormDB, + anthrovePost: invalidPost, }, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := CreateAnthrovePostNode(tt.args.ctx, tt.args.db, tt.args.anthrovePostID, tt.args.anthroveRating); (err != nil) != tt.wantErr { - t.Errorf("CreateAnthrovePostNode() error = %v, wantErr %v", err, tt.wantErr) + if err := CreatePost(tt.args.ctx, tt.args.db, tt.args.anthrovePost); (err != nil) != tt.wantErr { + t.Errorf("CreatePost() error = %v, wantErr %v", err, tt.wantErr) } }) } } -func TestCheckIfAnthrovePostNodeExistsByAnthroveID(t *testing.T) { +func TestGetPostByAnthroveID(t *testing.T) { // Setup trow away container ctx := context.Background() container, gormDB, err := test.StartPostgresContainer(ctx) @@ -69,68 +81,284 @@ func TestCheckIfAnthrovePostNodeExistsByAnthroveID(t *testing.T) { } defer container.Terminate(ctx) - // Setup Test + // Setup Tests - err = CreateAnthrovePostNode(ctx, gormDB, "1234", "safe") + post := &models.Post{ + BaseModel: models.BaseModel{ + ID: fmt.Sprintf("%025s", "1"), + }, + Rating: "safe", + } + + err = CreatePost(ctx, gormDB, post) if err != nil { - t.Fatal(err) + t.Fatal("Could not create post", err) } // Test - type args struct { ctx context.Context db *gorm.DB - anthrovePostID models.AnthrovePostID + anthrovePostID string } tests := []struct { name string args args - want bool + want *models.Post wantErr bool }{ { - name: "Test 1: Valid AnthroveID", + name: "Test 1: Valid anthrovePostID", + args: args{ + ctx: ctx, + db: gormDB, + anthrovePostID: post.ID, + }, + want: post, + wantErr: false, + }, + { + name: "Test 2: Invalid anthrovePostID", args: args{ ctx: ctx, db: gormDB, anthrovePostID: "1234", }, - want: true, - wantErr: false, + want: nil, + wantErr: true, }, { - name: "Test 2: Invalid AnthroveID", - args: args{ - ctx: ctx, - db: gormDB, - anthrovePostID: "123456", - }, - want: false, - wantErr: false, - }, - { - name: "Test 3: No AnthroveID", + name: "Test 3: No anthrovePostID", args: args{ ctx: ctx, db: gormDB, anthrovePostID: "", }, - want: false, + want: nil, wantErr: true, }, } - for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := CheckIfAnthrovePostNodeExistsByAnthroveID(tt.args.ctx, tt.args.db, tt.args.anthrovePostID) + got, err := GetPostByAnthroveID(tt.args.ctx, tt.args.db, tt.args.anthrovePostID) if (err != nil) != tt.wantErr { - t.Errorf("CheckIfAnthrovePostNodeExistsByAnthroveID() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetPostByAnthroveID() error = %v, wantErr %v", err, tt.wantErr) return } - if got != tt.want { - t.Errorf("CheckIfAnthrovePostNodeExistsByAnthroveID() got = %v, want %v", got, tt.want) + if !checkPost(got, tt.want) { + t.Errorf("GetPostByAnthroveID() got = %v, want %v", got, tt.want) } }) } } + +func TestGetPostBySourceURL(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Tests + post := &models.Post{ + BaseModel: models.BaseModel{ + ID: fmt.Sprintf("%025s", "1"), + }, + Rating: "safe", + } + + err = CreatePost(ctx, gormDB, post) + if err != nil { + t.Fatal("Could not create post", err) + } + + source := models.Source{ + BaseModel: models.BaseModel{ID: fmt.Sprintf("%025s", "1")}, + DisplayName: "e621", + Domain: "e621.net", + Icon: "https://e621.net/icon.ico", + } + + err = CreateSourceNode(ctx, gormDB, &source) + if err != nil { + t.Fatal("Could not create source", err) + } + + err = EstablishAnthrovePostToSourceLink(ctx, gormDB, post.ID, source.Domain) + if err != nil { + t.Fatal("Could not create source reference", err) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + sourceURL string + } + tests := []struct { + name string + args args + want *models.Post + wantErr bool + }{ + { + name: "Test 1: Valid sourceURL", + args: args{ + ctx: ctx, + db: gormDB, + sourceURL: source.Domain, + }, + want: post, + wantErr: false, + }, + { + name: "Test 2: Invalid sourceURL", + args: args{ + ctx: ctx, + db: gormDB, + sourceURL: "1234", + }, + want: nil, + wantErr: false, + }, + { + name: "Test 3: No sourceURL", + args: args{ + ctx: ctx, + db: gormDB, + sourceURL: "", + }, + want: nil, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetPostBySourceURL(tt.args.ctx, tt.args.db, tt.args.sourceURL) + if (err != nil) != tt.wantErr { + t.Errorf("GetPostBySourceURL() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !checkPost(got, tt.want) { + t.Errorf("GetPostBySourceURL() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGetPostBySourceID(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Tests + + post := &models.Post{ + BaseModel: models.BaseModel{ + ID: fmt.Sprintf("%025s", "1"), + }, + Rating: "safe", + } + + err = CreatePost(ctx, gormDB, post) + if err != nil { + t.Fatal("Could not create post", err) + } + + source := models.Source{ + BaseModel: models.BaseModel{ID: fmt.Sprintf("%025s", "1")}, + DisplayName: "e621", + Domain: "e621.net", + Icon: "https://e621.net/icon.ico", + } + + err = CreateSourceNode(ctx, gormDB, &source) + if err != nil { + t.Fatal("Could not create source", err) + } + + err = EstablishAnthrovePostToSourceLink(ctx, gormDB, post.ID, source.Domain) + if err != nil { + t.Fatal("Could not create source reference", err) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + sourceID string + } + + tests := []struct { + name string + args args + want *models.Post + wantErr bool + }{ + { + name: "Test 1: Valid sourceID", + args: args{ + ctx: ctx, + db: gormDB, + sourceID: source.ID, + }, + want: post, + wantErr: false, + }, + { + name: "Test 2: Invalid sourceID", + args: args{ + ctx: ctx, + db: gormDB, + sourceID: "1234", + }, + want: nil, + wantErr: false, + }, + { + name: "Test 3: No sourceID", + args: args{ + ctx: ctx, + db: gormDB, + sourceID: "", + }, + want: nil, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetPostBySourceID(tt.args.ctx, tt.args.db, tt.args.sourceID) + if (err != nil) != tt.wantErr { + t.Errorf("GetPostBySourceID() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !checkPost(got, tt.want) { + t.Errorf("GetPostBySourceID() got = %v, want %v", got, tt.want) + } + }) + } +} + +func checkPost(got *models.Post, want *models.Post) bool { + + if got == nil { + return true + } + + if got.ID != want.ID { + return false + } + + if got.Rating != want.Rating { + return false + } + + return true +} diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index c6d020f..7f319e0 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" ) -func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, sourceDomain string, anthrovePostRelationship *models.PostReference) error { +func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrovePostID string, sourceDomain string) error { var source models.Source var err error @@ -19,9 +19,9 @@ func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrov // Establish the relationship err = db.WithContext(ctx).Create(models.PostReference{ - PostID: string(anthrovePostID), + PostID: anthrovePostID, SourceID: source.ID, - URL: anthrovePostRelationship.URL, + URL: sourceDomain, }).Error if err != nil { @@ -55,7 +55,7 @@ func EstablishUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID st return nil } -func CheckUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) (bool, error) { +func CheckUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID string, anthrovePostID string) (bool, error) { var count int64 err := db.WithContext(ctx).Model(&models.UserFavorite{}).Where("user_id = ? AND post_id = ?", string(anthroveUserID), string(anthrovePostID)).Count(&count).Error if err != nil { diff --git a/internal/postgres/relationships_test.go b/internal/postgres/relationships_test.go index b96a5f3..7d2bc56 100644 --- a/internal/postgres/relationships_test.go +++ b/internal/postgres/relationships_test.go @@ -2,13 +2,14 @@ package postgres import ( "context" + "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/test" "gorm.io/gorm" "testing" ) -func TestEstablishAnthrovePostToSourceLink(t *testing.T) { +func TestCheckUserToPostLink(t *testing.T) { // Setup trow away container ctx := context.Background() @@ -19,8 +20,118 @@ func TestEstablishAnthrovePostToSourceLink(t *testing.T) { defer container.Terminate(ctx) // Setup Test + err = CreateUser(ctx, gormDB, "1") + if err != nil { + t.Fatal(err) + } - err = CreateAnthrovePostNode(ctx, gormDB, "1234", "safe") + post := &models.Post{ + BaseModel: models.BaseModel{ + ID: fmt.Sprintf("%025s", "1"), + }, + Rating: "safe", + } + + err = CreatePost(ctx, gormDB, post) + if err != nil { + t.Fatal(err) + } + + err = EstablishUserToPostLink(ctx, gormDB, "1", post.ID) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + anthroveUserID string + anthrovePostID string + } + tests := []struct { + name string + args args + want bool + wantErr bool + }{ + { + name: "Test 1: Valid AnthroveUserID and AnthrovePostID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + anthrovePostID: post.ID, + }, + want: true, + wantErr: false, + }, + { + name: "Test 2: Valid AnthroveUserID and invalid AnthrovePostID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + anthrovePostID: "qadw", + }, + want: false, + wantErr: false, + }, + { + name: "Test 3: Valid AnthrovePostID and invalid AnthroveUserID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "123", + anthrovePostID: post.ID, + }, + want: false, + wantErr: false, + }, + { + name: "Test 4: Invalid AnthrovePostID and invalid AnthroveUserID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "123", + anthrovePostID: "123456", + }, + want: false, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := CheckUserToPostLink(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.anthrovePostID) + if (err != nil) != tt.wantErr { + t.Errorf("CheckUserToPostLink() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("CheckUserToPostLink() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestEstablishAnthrovePostToSourceLink(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + post := &models.Post{ + BaseModel: models.BaseModel{ + ID: fmt.Sprintf("%025s", "1"), + }, + Rating: "safe", + } + + err = CreatePost(ctx, gormDB, post) if err != nil { t.Fatal(err) } @@ -36,12 +147,12 @@ func TestEstablishAnthrovePostToSourceLink(t *testing.T) { } // Test - type args struct { - ctx context.Context - db *gorm.DB - anthrovePostID models.AnthrovePostID - anthroveSourceDomain string + ctx context.Context + db *gorm.DB + anthrovePostID string + sourceDomain string + anthrovePostRelationship *models.PostReference } tests := []struct { name string @@ -51,47 +162,47 @@ func TestEstablishAnthrovePostToSourceLink(t *testing.T) { { name: "Test 1: Valid AnthrovePostID and anthroveSourceDomain", args: args{ - ctx: ctx, - db: gormDB, - anthrovePostID: "1234", - anthroveSourceDomain: "e621.net", + ctx: ctx, + db: gormDB, + anthrovePostID: post.ID, + sourceDomain: "e621.net", }, wantErr: false, }, { name: "Test 2: Invalid AnthrovePostID and Valid anthroveSourceDomain", args: args{ - ctx: ctx, - db: gormDB, - anthrovePostID: "123456", - anthroveSourceDomain: "e621.net", + ctx: ctx, + db: gormDB, + anthrovePostID: "123456", + sourceDomain: "e621.net", }, wantErr: true, }, { name: "Test 3: Invalid anthroveSourceDomain and Valid AnthrovePostID", args: args{ - ctx: ctx, - db: gormDB, - anthrovePostID: "1234", - anthroveSourceDomain: "fa.banana", + ctx: ctx, + db: gormDB, + anthrovePostID: "1234", + sourceDomain: "fa.banana", }, wantErr: true, }, { name: "Test 4: Invalid anthroveSourceDomain and Invalid AnthrovePostID", args: args{ - ctx: ctx, - db: gormDB, - anthrovePostID: "696969", - anthroveSourceDomain: "hehe.funny.number", + ctx: ctx, + db: gormDB, + anthrovePostID: "696969", + sourceDomain: "hehe.funny.number", }, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := EstablishAnthrovePostToSourceLink(tt.args.ctx, tt.args.db, tt.args.anthrovePostID, tt.args.anthroveSourceDomain); (err != nil) != tt.wantErr { + if err := EstablishAnthrovePostToSourceLink(tt.args.ctx, tt.args.db, tt.args.anthrovePostID, tt.args.sourceDomain); (err != nil) != tt.wantErr { t.Errorf("EstablishAnthrovePostToSourceLink() error = %v, wantErr %v", err, tt.wantErr) } }) @@ -113,7 +224,14 @@ func TestEstablishUserToPostLink(t *testing.T) { t.Fatal(err) } - err = CreateAnthrovePostNode(ctx, gormDB, "1234", "safe") + post := &models.Post{ + BaseModel: models.BaseModel{ + ID: fmt.Sprintf("%025s", "1"), + }, + Rating: "safe", + } + + err = CreatePost(ctx, gormDB, post) if err != nil { t.Fatal(err) } @@ -122,8 +240,8 @@ func TestEstablishUserToPostLink(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - anthroveUserID models.AnthroveUserID - anthrovePostID models.AnthrovePostID + anthroveUserID string + anthrovePostID string } tests := []struct { name string @@ -136,7 +254,7 @@ func TestEstablishUserToPostLink(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "1", - anthrovePostID: "1234", + anthrovePostID: post.ID, }, wantErr: false, }, @@ -179,101 +297,3 @@ func TestEstablishUserToPostLink(t *testing.T) { }) } } - -func TestCheckUserToPostLink(t *testing.T) { - // Setup trow away container - ctx := context.Background() - container, gormDB, err := test.StartPostgresContainer(ctx) - if err != nil { - t.Fatalf("Could not start PostgreSQL container: %v", err) - } - defer container.Terminate(ctx) - - // Setup Test - - err = CreateUser(ctx, gormDB, "1") - if err != nil { - t.Fatal(err) - } - - err = CreateAnthrovePostNode(ctx, gormDB, "1234", "safe") - if err != nil { - t.Fatal(err) - } - - err = EstablishUserToPostLink(ctx, gormDB, "1", "1234") - if err != nil { - t.Fatal(err) - } - - // Test - type args struct { - ctx context.Context - db *gorm.DB - anthroveUserID models.AnthroveUserID - anthrovePostID models.AnthrovePostID - } - tests := []struct { - name string - args args - want bool - wantErr bool - }{ - { - name: "Test 1: Valid AnthroveUserID and AnthrovePostID", - args: args{ - ctx: ctx, - db: gormDB, - anthroveUserID: "1", - anthrovePostID: "1234", - }, - want: true, - wantErr: false, - }, - { - name: "Test 2: Valid AnthroveUserID and invalid AnthrovePostID", - args: args{ - ctx: ctx, - db: gormDB, - anthroveUserID: "1", - anthrovePostID: "123456", - }, - want: false, - wantErr: false, - }, - { - name: "Test 3: Valid AnthrovePostID and invalid AnthroveUserID", - args: args{ - ctx: ctx, - db: gormDB, - anthroveUserID: "123", - anthrovePostID: "1234", - }, - want: false, - wantErr: false, - }, - { - name: "Test 4: Invalid AnthrovePostID and invalid AnthroveUserID", - args: args{ - ctx: ctx, - db: gormDB, - anthroveUserID: "123", - anthrovePostID: "123456", - }, - want: false, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := CheckUserToPostLink(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.anthrovePostID) - if (err != nil) != tt.wantErr { - t.Errorf("CheckUserToPostLink() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got != tt.want { - t.Errorf("CheckUserToPostLink() got = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/internal/postgres/source_test.go b/internal/postgres/source_test.go index 99fd7b8..f0a3103 100644 --- a/internal/postgres/source_test.go +++ b/internal/postgres/source_test.go @@ -19,13 +19,13 @@ func TestCreateSourceNode(t *testing.T) { // Setup Test - validAnthroveSource := &models.Source{ + validSource := &models.Source{ DisplayName: "e621", Domain: "e621.net", Icon: "icon.e621.net", } - invalidAnthroveSource := &models.Source{ + invalidSource := &models.Source{ Domain: "", } @@ -45,7 +45,7 @@ func TestCreateSourceNode(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveSource: validAnthroveSource, + anthroveSource: validSource, }, wantErr: false, }, @@ -54,7 +54,7 @@ func TestCreateSourceNode(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveSource: invalidAnthroveSource, + anthroveSource: invalidSource, }, wantErr: true, }, @@ -63,7 +63,7 @@ func TestCreateSourceNode(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveSource: validAnthroveSource, + anthroveSource: validSource, }, wantErr: false, }, diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 40e0f68..885ffa3 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -8,7 +8,7 @@ import ( "gorm.io/gorm" ) -func CreateTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { +func createTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { resultTag := db.WithContext(ctx).Where(tag).Create(tag) @@ -24,12 +24,16 @@ func CreateTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { return nil } -func CreateTagNodeWitRelation(ctx context.Context, db *gorm.DB, PostID models.AnthrovePostID, tag *models.Tag) error { +func CreateTagNodeWitRelation(ctx context.Context, db *gorm.DB, PostID string, tag *models.Tag) error { if PostID == "" { return fmt.Errorf("PostID is empty") } + if tag == nil { + return fmt.Errorf("tag is nill") + } + pgPost := models.Post{ BaseModel: models.BaseModel{ ID: string(PostID), diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index c0b323a..00b0b46 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -2,6 +2,7 @@ package postgres import ( "context" + "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/test" "gorm.io/gorm" @@ -19,7 +20,14 @@ func TestCreateTagNodeWitRelation(t *testing.T) { // Setup Test - err = CreateAnthrovePostNode(ctx, gormDB, "1234", "safe") + post := &models.Post{ + BaseModel: models.BaseModel{ + ID: fmt.Sprintf("%025s", "1"), + }, + Rating: "safe", + } + + err = CreatePost(ctx, gormDB, post) if err != nil { t.Fatal(err) } @@ -33,7 +41,7 @@ func TestCreateTagNodeWitRelation(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - PostID models.AnthrovePostID + PostID string tag *models.Tag } tests := []struct { @@ -46,17 +54,17 @@ func TestCreateTagNodeWitRelation(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - PostID: "1234", + PostID: post.ID, tag: tag, }, wantErr: false, }, { - name: "Test 2: Valid PostID and invalid Tag", + name: "Test 2: Valid PostID and no Tag", args: args{ ctx: ctx, db: gormDB, - PostID: "1234", + PostID: post.ID, tag: nil, }, wantErr: true, @@ -118,7 +126,7 @@ func TestGetTags(t *testing.T) { } for _, tag := range tags { - err = CreateTag(ctx, gormDB, &tag) + err = createTag(ctx, gormDB, &tag) if err != nil { t.Fatal(err) } diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 8afd07f..fed56f9 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -8,7 +8,7 @@ import ( "gorm.io/gorm" ) -func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) error { +func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID string) error { if anthroveUserID == "" { return fmt.Errorf("anthroveUserID cannot be empty") @@ -20,7 +20,7 @@ func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Anthrove }, } - err := db.WithContext(ctx).Create(&user).Error + err := db.WithContext(ctx).FirstOrCreate(&user).Error if err != nil { log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, @@ -31,12 +31,17 @@ func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Anthrove return nil } -func CreateUserNodeWithSourceRelation(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error { +func CreateUserNodeWithSourceRelation(ctx context.Context, db *gorm.DB, anthroveUserID string, sourceDomain string, userID string, username string) error { if anthroveUserID == "" || username == "" || userID == "" { return fmt.Errorf("anthroveUserID cannot be empty") } + err := CreateUser(ctx, db, anthroveUserID) + if err != nil { + return err + } + source := models.Source{ Domain: sourceDomain, } @@ -49,10 +54,11 @@ func CreateUserNodeWithSourceRelation(ctx context.Context, db *gorm.DB, anthrove } userSource := models.UserSource{ - User: models.User{BaseModel: models.BaseModel{ID: string(anthroveUserID)}}, + User: models.User{BaseModel: models.BaseModel{ID: anthroveUserID}}, SourceID: source.ID, AccountUsername: username, AccountID: userID, + UserID: anthroveUserID, } if err := db.WithContext(ctx).FirstOrCreate(&userSource).Error; err != nil { @@ -183,9 +189,9 @@ func GetSpecifiedUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID return userSourceMap, nil } -func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveUserID, error) { +func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]string, error) { var users []models.User - var userIDs []models.AnthroveUserID + var userIDs []string err := db.WithContext(ctx).Model(&models.User{}).Find(&users).Error if err != nil { @@ -194,7 +200,7 @@ func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveU } for _, user := range users { - userIDs = append(userIDs, models.AnthroveUserID(user.ID)) + userIDs = append(userIDs, user.ID) } log.WithFields(log.Fields{ @@ -204,7 +210,7 @@ func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveU return userIDs, nil } -func GetUserFavoriteNodeWithPagination(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) { +func GetUserFavoriteNodeWithPagination(ctx context.Context, db *gorm.DB, anthroveUserID string, skip int, limit int) (*models.FavoriteList, error) { var userFavorites []models.UserFavorite var favoritePosts []models.Post @@ -257,6 +263,7 @@ func GetUserTagNodeWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, ant name string typeName string }]int) + for _, userFavorite := range userFavorites { var post models.Post err = db.WithContext(ctx).Preload("Tags").First(&post, "id = ?", userFavorite.PostID).Error diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index b0742c5..cae2b0c 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" "git.dragse.it/anthrove/otter-space-sdk/test" "gorm.io/gorm" "reflect" @@ -26,7 +25,7 @@ func TestCreateUser(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - anthroveUserID models.AnthroveUserID + anthroveUserID string } tests := []struct { name string @@ -86,7 +85,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - anthroveUserID models.AnthroveUserID + anthroveUserID string sourceDomain string userID string username string @@ -102,7 +101,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "1", - sourceDomain: "e621.net", + sourceDomain: source.Domain, userID: "e1", username: "marius", }, @@ -114,7 +113,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "2", - sourceDomain: "e621.net", + sourceDomain: source.Domain, userID: "e1", username: "marius", }, @@ -126,7 +125,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "", - sourceDomain: "e621.net", + sourceDomain: source.Domain, userID: "e1", username: "marius", }, @@ -150,7 +149,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "1", - sourceDomain: "e621.net", + sourceDomain: source.Domain, userID: "", username: "marius", }, @@ -162,7 +161,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "1", - sourceDomain: "e621.net", + sourceDomain: source.Domain, userID: "aa", username: "", }, @@ -189,7 +188,7 @@ func TestGetAllAnthroveUserIDs(t *testing.T) { // Setup Test - users := []models.AnthroveUserID{"1", "2", "3"} + users := []string{"1", "2", "3"} for _, user := range users { err = CreateUser(ctx, gormDB, user) @@ -206,7 +205,7 @@ func TestGetAllAnthroveUserIDs(t *testing.T) { tests := []struct { name string args args - want []models.AnthroveUserID + want []string wantErr bool }{ { @@ -233,82 +232,6 @@ func TestGetAllAnthroveUserIDs(t *testing.T) { } } -func TestGetAnthroveUser(t *testing.T) { - // Setup trow away container - ctx := context.Background() - container, gormDB, err := test.StartPostgresContainer(ctx) - if err != nil { - t.Fatalf("Could not start PostgreSQL container: %v", err) - } - defer container.Terminate(ctx) - - // Setup Test - - user := graphModels.AnthroveUser{ - UserID: "1", - } - err = CreateUser(ctx, gormDB, user.UserID) - if err != nil { - t.Fatal(err) - } - - // Test - type args struct { - ctx context.Context - db *gorm.DB - anthroveUserID models.AnthroveUserID - } - tests := []struct { - name string - args args - want *graphModels.AnthroveUser - wantErr bool - }{ - { - name: "Test 1: Valid AnthroveUserID", - args: args{ - ctx: ctx, - db: gormDB, - anthroveUserID: "1", - }, - want: &user, - wantErr: false, - }, - { - name: "Test 2: Invalid AnthroveUserID", - args: args{ - ctx: ctx, - db: gormDB, - anthroveUserID: "2", - }, - want: nil, - wantErr: true, - }, - { - name: "Test 3: No AnthroveUserID", - args: args{ - ctx: ctx, - db: gormDB, - anthroveUserID: "", - }, - want: nil, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := GetAnthroveUser(tt.args.ctx, tt.args.db, tt.args.anthroveUserID) - if (err != nil) != tt.wantErr { - t.Errorf("GetAnthroveUser() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetAnthroveUser() got = %v, want %v", got, tt.want) - } - }) - } -} - func TestGetSpecifiedUserSourceLink(t *testing.T) { // Setup trow away container ctx := context.Background() @@ -319,31 +242,33 @@ func TestGetSpecifiedUserSourceLink(t *testing.T) { defer container.Terminate(ctx) // Setup Test - source := &models.Source{ - DisplayName: "e621", - Domain: "e621.net", + + expectedResult := make(map[string]models.UserSource) + expectedResult["e621"] = models.UserSource{ + UserID: "e1", + AccountUsername: "euser", + Source: models.Source{ + DisplayName: "e621", + Domain: "e621.net", + }, } + + source := &models.Source{ + DisplayName: expectedResult["e621"].Source.DisplayName, + Domain: expectedResult["e621"].Source.Domain, + } + err = CreateSourceNode(ctx, gormDB, source) if err != nil { t.Fatal(err) } - expectedResult := make(map[string]graphModels.AnthroveUserRelationship) - expectedResult["e621"] = graphModels.AnthroveUserRelationship{ - UserID: "e1", - Username: "euser", - Source: graphModels.AnthroveSource{ - DisplayName: source.DisplayName, - Domain: source.Domain, - }, - } - - err = CreateUserNodeWithSourceRelation(ctx, gormDB, "1", source.Domain, expectedResult["e621"].UserID, expectedResult["e621"].Username) + err = CreateUserNodeWithSourceRelation(ctx, gormDB, "1", source.Domain, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) if err != nil { t.Fatal(err) } - // Test + // Test type args struct { ctx context.Context db *gorm.DB @@ -353,7 +278,7 @@ func TestGetSpecifiedUserSourceLink(t *testing.T) { tests := []struct { name string args args - want map[string]graphModels.AnthroveUserRelationship + want map[string]models.UserSource wantErr bool }{ { @@ -431,7 +356,7 @@ func TestGetSpecifiedUserSourceLink(t *testing.T) { return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetSpecifiedUserSourceLink() got = %v, expectedResult %v", got, tt.want) + t.Errorf("GetSpecifiedUserSourceLink() got = %v, want %v", got, tt.want) } }) } @@ -448,52 +373,41 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { // Setup Test - expectedResultPostsGraph := []graphModels.FavoritePost{ + expectedResultPosts := []models.Post{ { - AnthrovePost: graphModels.AnthrovePost{ - PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post1")), - Rating: "safe", - }, + BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post1")}, + Rating: "safe", }, { - AnthrovePost: graphModels.AnthrovePost{ - PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post2")), - Rating: "safe", - }, + + BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post2")}, + Rating: "safe", }, { - AnthrovePost: graphModels.AnthrovePost{ - PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post3")), - Rating: "explicit", - }, + BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post3")}, + Rating: "explicit", }, { - AnthrovePost: graphModels.AnthrovePost{ - PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post4")), - Rating: "explicit", - }, + BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post4")}, + Rating: "explicit", }, { - AnthrovePost: graphModels.AnthrovePost{ - PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post5")), - Rating: "questionable", - }, + BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post5")}, + Rating: "questionable", }, { - AnthrovePost: graphModels.AnthrovePost{ - PostID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post6")), - Rating: "safe", - }, + BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post6")}, + Rating: "safe", }, } - expectedResult := &graphModels.FavoriteList{ - Posts: expectedResultPostsGraph, + expectedResult := &models.FavoriteList{ + Posts: expectedResultPosts, } - expectedResult2 := &graphModels.FavoriteList{ - Posts: expectedResultPostsGraph[2:], + expectedResult2 := &models.FavoriteList{ + Posts: expectedResultPosts[2:], } - expectedResult3 := &graphModels.FavoriteList{ - Posts: expectedResultPostsGraph[:3], + expectedResult3 := &models.FavoriteList{ + Posts: expectedResultPosts[:3], } err = CreateUser(ctx, gormDB, "1") @@ -501,39 +415,12 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { t.Fatal(err) } - expectedResultPostsPg := []models.Post{ - { - BaseModel: models.BaseModel{ID: "Post1"}, - Rating: "safe", - }, - { - BaseModel: models.BaseModel{ID: "Post2"}, - Rating: "safe", - }, - { - BaseModel: models.BaseModel{ID: "Post3"}, - Rating: "explicit", - }, - { - BaseModel: models.BaseModel{ID: "Post4"}, - Rating: "explicit", - }, - { - BaseModel: models.BaseModel{ID: "Post5"}, - Rating: "questionable", - }, - { - BaseModel: models.BaseModel{ID: "Post6"}, - Rating: "safe", - }, - } - - for _, expectedResultPost := range expectedResultPostsPg { - err = CreateAnthrovePostNode(ctx, gormDB, models.AnthrovePostID(expectedResultPost.ID), expectedResultPost.Rating) + for _, expectedResultPost := range expectedResultPosts { + err = CreatePost(ctx, gormDB, &expectedResultPost) if err != nil { t.Fatal(err) } - err = EstablishUserToPostLink(ctx, gormDB, "1", models.AnthrovePostID(expectedResultPost.ID)) + err = EstablishUserToPostLink(ctx, gormDB, "1", expectedResultPost.ID) if err != nil { t.Fatal(err) } @@ -543,14 +430,14 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - anthroveUserID models.AnthroveUserID + anthroveUserID string skip int limit int } tests := []struct { name string args args - want *graphModels.FavoriteList + want *models.FavoriteList wantErr bool }{ { @@ -620,7 +507,7 @@ func TestGetUserFavoritesCount(t *testing.T) { t.Fatal(err) } - expectedResultPostsPg := []models.Post{ + expectedResultPosts := []models.Post{ { BaseModel: models.BaseModel{ID: "Post1"}, Rating: "safe", @@ -647,12 +534,12 @@ func TestGetUserFavoritesCount(t *testing.T) { }, } - for _, expectedResultPost := range expectedResultPostsPg { - err = CreateAnthrovePostNode(ctx, gormDB, models.AnthrovePostID(expectedResultPost.ID), expectedResultPost.Rating) + for _, post := range expectedResultPosts { + err = CreatePost(ctx, gormDB, &post) if err != nil { t.Fatal(err) } - err = EstablishUserToPostLink(ctx, gormDB, "1", models.AnthrovePostID(expectedResultPost.ID)) + err = EstablishUserToPostLink(ctx, gormDB, "1", post.ID) if err != nil { t.Fatal(err) } @@ -715,7 +602,7 @@ func TestGetUserFavoritesCount(t *testing.T) { } } -func TestGetUserSourceLink(t *testing.T) { +func TestGetUserSourceLinks(t *testing.T) { // Setup trow away containert ctx := context.Background() container, gormDB, err := test.StartPostgresContainer(ctx) @@ -725,51 +612,51 @@ func TestGetUserSourceLink(t *testing.T) { defer container.Terminate(ctx) // Setup Test - - esource := &models.Source{ + eSource := &models.Source{ DisplayName: "e621", Domain: "e621.net", } - err = CreateSourceNode(ctx, gormDB, esource) + err = CreateSourceNode(ctx, gormDB, eSource) if err != nil { t.Fatal(err) } - fasource := &models.Source{ + faSource := &models.Source{ DisplayName: "fa", Domain: "fa.net", } - err = CreateSourceNode(ctx, gormDB, fasource) + err = CreateSourceNode(ctx, gormDB, faSource) if err != nil { t.Fatal(err) } - expectedResult := make(map[string]graphModels.AnthroveUserRelationship) - expectedResult["e621"] = graphModels.AnthroveUserRelationship{ - UserID: "e1", - Username: "euser", - Source: graphModels.AnthroveSource{ - DisplayName: esource.DisplayName, - Domain: esource.Domain, + expectedResult := make(map[string]models.UserSource) + expectedResult["e621"] = models.UserSource{ + UserID: "e1", + AccountUsername: "e621-user", + Source: models.Source{ + DisplayName: eSource.DisplayName, + Domain: eSource.Domain, }, } - expectedResult["fa"] = graphModels.AnthroveUserRelationship{ - UserID: "fa1", - Username: "fauser", - Source: graphModels.AnthroveSource{ - DisplayName: fasource.DisplayName, - Domain: fasource.Domain, + expectedResult["fa"] = models.UserSource{ + UserID: "fa1", + AccountUsername: "fa-user", + Source: models.Source{ + DisplayName: faSource.DisplayName, + Domain: faSource.Domain, }, } - err = CreateUserNodeWithSourceRelation(ctx, gormDB, "1", esource.Domain, expectedResult["e621"].UserID, expectedResult["e621"].Username) + err = CreateUserNodeWithSourceRelation(ctx, gormDB, "1", eSource.Domain, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) if err != nil { t.Fatal(err) } - err = CreateUserNodeWithSourceRelation(ctx, gormDB, "1", fasource.Domain, expectedResult["fa"].UserID, expectedResult["fa"].Username) + err = CreateUserNodeWithSourceRelation(ctx, gormDB, "1", faSource.Domain, expectedResult["fa"].UserID, expectedResult["fa"].AccountUsername) if err != nil { t.Fatal(err) } + // Test type args struct { ctx context.Context @@ -779,7 +666,7 @@ func TestGetUserSourceLink(t *testing.T) { tests := []struct { name string args args - want map[string]graphModels.AnthroveUserRelationship + want map[string]models.UserSource wantErr bool }{ { @@ -829,11 +716,11 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { } for _, post := range posts { - err = CreateAnthrovePostNode(ctx, gormDB, models.AnthrovePostID(post.ID), post.Rating) + err = CreatePost(ctx, gormDB, &post) if err != nil { t.Fatal(err) } - err = EstablishUserToPostLink(ctx, gormDB, "1", models.AnthrovePostID(post.ID)) + err = EstablishUserToPostLink(ctx, gormDB, "1", post.ID) if err != nil { t.Fatal(err) } @@ -846,32 +733,32 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { } for i, tag := range tags { - err = CreateTagNodeWitRelation(ctx, gormDB, models.AnthrovePostID(posts[i].ID), &tag) + err = CreateTagNodeWitRelation(ctx, gormDB, posts[i].ID, &tag) if err != nil { t.Fatal(err) } } - expectedResult := []graphModels.TagsWithFrequency{ + expectedResult := []models.TagsWithFrequency{ { Frequency: 1, - Tags: graphModels.AnthroveTag{ + Tags: models.Tag{ Name: tags[0].Name, - Type: string(tags[0].Type), + Type: tags[0].Type, }, }, { Frequency: 1, - Tags: graphModels.AnthroveTag{ + Tags: models.Tag{ Name: tags[1].Name, - Type: string(tags[1].Type), + Type: tags[1].Type, }, }, { Frequency: 1, - Tags: graphModels.AnthroveTag{ + Tags: models.Tag{ Name: tags[2].Name, - Type: string(tags[2].Type), + Type: tags[2].Type, }, }, } @@ -885,11 +772,11 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { tests := []struct { name string args args - want []graphModels.TagsWithFrequency + want []models.TagsWithFrequency wantErr bool }{ { - name: "", + name: "Test 1: Get Data", args: args{ ctx: ctx, db: gormDB, diff --git a/pkg/database/migrations/001_inital_database.sql b/pkg/database/migrations/001_inital_database.sql index 749a337..e6758e3 100644 --- a/pkg/database/migrations/001_inital_database.sql +++ b/pkg/database/migrations/001_inital_database.sql @@ -91,7 +91,8 @@ CREATE TABLE "UserSource" ( user_id TEXT REFERENCES "User" (id), source_id TEXT REFERENCES "Source" (id), - scrape_time_interval TEXT account_username TEXT, + scrape_time_interval TEXT, + account_username TEXT, account_id TEXT, PRIMARY KEY (user_id, source_id), UNIQUE (account_username, account_id) diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index ac996c0..0cfc1bd 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -73,7 +73,7 @@ func (p *postgresqlConnection) AddSource(ctx context.Context, anthroveSource *mo } func (p *postgresqlConnection) AddPost(ctx context.Context, anthrovePost *models.Post) error { - return postgres.CreateAnthrovePostNode(ctx, p.db, anthrovePost) + return postgres.CreatePost(ctx, p.db, anthrovePost) } func (p *postgresqlConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error { -- 2.45.1 From 8a0229eb23766f93abefc6f82ade95268b822ba1 Mon Sep 17 00:00:00 2001 From: soxx Date: Sun, 23 Jun 2024 21:23:38 +0200 Subject: [PATCH 067/124] test(postgres): renamed functions to be more clear Signed-off-by: soxx --- internal/postgres/post_test.go | 8 +- internal/postgres/relationships.go | 6 +- internal/postgres/relationships_test.go | 18 ++-- internal/postgres/source.go | 12 +-- internal/postgres/source_test.go | 20 ++--- internal/postgres/tag.go | 4 +- internal/postgres/tag_test.go | 6 +- internal/postgres/user.go | 26 +++--- internal/postgres/user_test.go | 112 ++++++++++++------------ pkg/database/database.go | 46 +++++----- pkg/database/postgres.go | 44 +++++----- 11 files changed, 153 insertions(+), 149 deletions(-) diff --git a/internal/postgres/post_test.go b/internal/postgres/post_test.go index 87d2690..098fe2b 100644 --- a/internal/postgres/post_test.go +++ b/internal/postgres/post_test.go @@ -181,12 +181,12 @@ func TestGetPostBySourceURL(t *testing.T) { Icon: "https://e621.net/icon.ico", } - err = CreateSourceNode(ctx, gormDB, &source) + err = CreateSource(ctx, gormDB, &source) if err != nil { t.Fatal("Could not create source", err) } - err = EstablishAnthrovePostToSourceLink(ctx, gormDB, post.ID, source.Domain) + err = CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, source.Domain) if err != nil { t.Fatal("Could not create source reference", err) } @@ -278,12 +278,12 @@ func TestGetPostBySourceID(t *testing.T) { Icon: "https://e621.net/icon.ico", } - err = CreateSourceNode(ctx, gormDB, &source) + err = CreateSource(ctx, gormDB, &source) if err != nil { t.Fatal("Could not create source", err) } - err = EstablishAnthrovePostToSourceLink(ctx, gormDB, post.ID, source.Domain) + err = CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, source.Domain) if err != nil { t.Fatal("Could not create source reference", err) } diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index 7f319e0..cade964 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" ) -func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrovePostID string, sourceDomain string) error { +func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthrovePostID string, sourceDomain string) error { var source models.Source var err error @@ -36,7 +36,7 @@ func EstablishAnthrovePostToSourceLink(ctx context.Context, db *gorm.DB, anthrov return nil } -func EstablishUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID string, anthrovePostID string) error { +func CreateReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthroveUserID string, anthrovePostID string) error { userFavorite := models.UserFavorite{ UserID: string(anthroveUserID), PostID: string(anthrovePostID), @@ -55,7 +55,7 @@ func EstablishUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID st return nil } -func CheckUserToPostLink(ctx context.Context, db *gorm.DB, anthroveUserID string, anthrovePostID string) (bool, error) { +func CheckReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthroveUserID string, anthrovePostID string) (bool, error) { var count int64 err := db.WithContext(ctx).Model(&models.UserFavorite{}).Where("user_id = ? AND post_id = ?", string(anthroveUserID), string(anthrovePostID)).Count(&count).Error if err != nil { diff --git a/internal/postgres/relationships_test.go b/internal/postgres/relationships_test.go index 7d2bc56..4d49f65 100644 --- a/internal/postgres/relationships_test.go +++ b/internal/postgres/relationships_test.go @@ -37,7 +37,7 @@ func TestCheckUserToPostLink(t *testing.T) { t.Fatal(err) } - err = EstablishUserToPostLink(ctx, gormDB, "1", post.ID) + err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", post.ID) if err != nil { t.Fatal(err) } @@ -102,13 +102,13 @@ func TestCheckUserToPostLink(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := CheckUserToPostLink(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.anthrovePostID) + got, err := CheckReferenceBetweenUserAndPost(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.anthrovePostID) if (err != nil) != tt.wantErr { - t.Errorf("CheckUserToPostLink() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("CheckReferenceBetweenUserAndPost() error = %v, wantErr %v", err, tt.wantErr) return } if got != tt.want { - t.Errorf("CheckUserToPostLink() got = %v, want %v", got, tt.want) + t.Errorf("CheckReferenceBetweenUserAndPost() got = %v, want %v", got, tt.want) } }) } @@ -141,7 +141,7 @@ func TestEstablishAnthrovePostToSourceLink(t *testing.T) { Domain: "e621.net", Icon: "icon.e621.net", } - err = CreateSourceNode(ctx, gormDB, source) + err = CreateSource(ctx, gormDB, source) if err != nil { t.Fatal(err) } @@ -202,8 +202,8 @@ func TestEstablishAnthrovePostToSourceLink(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := EstablishAnthrovePostToSourceLink(tt.args.ctx, tt.args.db, tt.args.anthrovePostID, tt.args.sourceDomain); (err != nil) != tt.wantErr { - t.Errorf("EstablishAnthrovePostToSourceLink() error = %v, wantErr %v", err, tt.wantErr) + if err := CreateReferenceBetweenPostAndSource(tt.args.ctx, tt.args.db, tt.args.anthrovePostID, tt.args.sourceDomain); (err != nil) != tt.wantErr { + t.Errorf("CreateReferenceBetweenPostAndSource() error = %v, wantErr %v", err, tt.wantErr) } }) } @@ -291,8 +291,8 @@ func TestEstablishUserToPostLink(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := EstablishUserToPostLink(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.anthrovePostID); (err != nil) != tt.wantErr { - t.Errorf("EstablishUserToPostLink() error = %v, wantErr %v", err, tt.wantErr) + if err := CreateReferenceBetweenUserAndPost(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.anthrovePostID); (err != nil) != tt.wantErr { + t.Errorf("CreateReferenceBetweenUserAndPost() error = %v, wantErr %v", err, tt.wantErr) } }) } diff --git a/internal/postgres/source.go b/internal/postgres/source.go index 5e4ecd5..ec889fd 100644 --- a/internal/postgres/source.go +++ b/internal/postgres/source.go @@ -9,8 +9,8 @@ import ( "gorm.io/gorm" ) -// CreateSourceNode creates a pgModels.Source -func CreateSourceNode(ctx context.Context, db *gorm.DB, anthroveSource *models.Source) error { +// CreateSource creates a pgModels.Source +func CreateSource(ctx context.Context, db *gorm.DB, anthroveSource *models.Source) error { if anthroveSource.Domain == "" { return fmt.Errorf("anthroveSource domain is required") @@ -31,8 +31,8 @@ func CreateSourceNode(ctx context.Context, db *gorm.DB, anthroveSource *models.S return nil } -// GetAllSourceNodes returns a list of all pgModels.Source -func GetAllSourceNodes(ctx context.Context, db *gorm.DB) ([]models.Source, error) { +// GetAllSource returns a list of all pgModels.Source +func GetAllSource(ctx context.Context, db *gorm.DB) ([]models.Source, error) { var sources []models.Source result := db.WithContext(ctx).Find(&sources) @@ -48,8 +48,8 @@ func GetAllSourceNodes(ctx context.Context, db *gorm.DB) ([]models.Source, error return sources, nil } -// GetSourceNodesByURL returns the first source it finds based on the domain -func GetSourceNodesByURL(ctx context.Context, db *gorm.DB, domain string) (*models.Source, error) { +// GetSourceByURL returns the first source it finds based on the domain +func GetSourceByURL(ctx context.Context, db *gorm.DB, domain string) (*models.Source, error) { var sources models.Source if domain == "" { diff --git a/internal/postgres/source_test.go b/internal/postgres/source_test.go index f0a3103..a6d7863 100644 --- a/internal/postgres/source_test.go +++ b/internal/postgres/source_test.go @@ -70,8 +70,8 @@ func TestCreateSourceNode(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := CreateSourceNode(tt.args.ctx, tt.args.db, tt.args.anthroveSource); (err != nil) != tt.wantErr { - t.Errorf("CreateSourceNode() error = %v, wantErr %v", err, tt.wantErr) + if err := CreateSource(tt.args.ctx, tt.args.db, tt.args.anthroveSource); (err != nil) != tt.wantErr { + t.Errorf("CreateSource() error = %v, wantErr %v", err, tt.wantErr) } }) } @@ -107,7 +107,7 @@ func TestGetAllSourceNodes(t *testing.T) { } for _, source := range sources { - err = CreateSourceNode(ctx, gormDB, &source) + err = CreateSource(ctx, gormDB, &source) if err != nil { t.Fatal(err) } @@ -136,13 +136,13 @@ func TestGetAllSourceNodes(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := GetAllSourceNodes(tt.args.ctx, tt.args.db) + got, err := GetAllSource(tt.args.ctx, tt.args.db) if (err != nil) != tt.wantErr { - t.Errorf("GetAllSourceNodes() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetAllSource() error = %v, wantErr %v", err, tt.wantErr) return } if !checkSourcesNode(got, tt.want) { - t.Errorf("GetAllSourceNodes() got = %v, want %v", got, tt.want) + t.Errorf("GetAllSource() got = %v, want %v", got, tt.want) } }) } @@ -165,7 +165,7 @@ func TestGetSourceNodesByURL(t *testing.T) { Icon: "icon.e621.net", } - err = CreateSourceNode(ctx, gormDB, source) + err = CreateSource(ctx, gormDB, source) if err != nil { t.Fatal(err) } @@ -215,13 +215,13 @@ func TestGetSourceNodesByURL(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := GetSourceNodesByURL(tt.args.ctx, tt.args.db, tt.args.domain) + got, err := GetSourceByURL(tt.args.ctx, tt.args.db, tt.args.domain) if (err != nil) != tt.wantErr { - t.Errorf("GetSourceNodesByURL() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetSourceByURL() error = %v, wantErr %v", err, tt.wantErr) return } if !checkSourceNode(got, tt.want) { - t.Errorf("GetSourceNodesByURL() got = %v, want %v", got, tt.want) + t.Errorf("GetSourceByURL() got = %v, want %v", got, tt.want) } }) } diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 885ffa3..4213b28 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -8,7 +8,7 @@ import ( "gorm.io/gorm" ) -func createTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { +func CreateTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { resultTag := db.WithContext(ctx).Where(tag).Create(tag) @@ -24,7 +24,7 @@ func createTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { return nil } -func CreateTagNodeWitRelation(ctx context.Context, db *gorm.DB, PostID string, tag *models.Tag) error { +func CreateTagAndReferenceToPost(ctx context.Context, db *gorm.DB, PostID string, tag *models.Tag) error { if PostID == "" { return fmt.Errorf("PostID is empty") diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index 00b0b46..d83d760 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -92,8 +92,8 @@ func TestCreateTagNodeWitRelation(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := CreateTagNodeWitRelation(tt.args.ctx, tt.args.db, tt.args.PostID, tt.args.tag); (err != nil) != tt.wantErr { - t.Errorf("CreateTagNodeWitRelation() error = %v, wantErr %v", err, tt.wantErr) + if err := CreateTagAndReferenceToPost(tt.args.ctx, tt.args.db, tt.args.PostID, tt.args.tag); (err != nil) != tt.wantErr { + t.Errorf("CreateTagAndReferenceToPost() error = %v, wantErr %v", err, tt.wantErr) } }) } @@ -126,7 +126,7 @@ func TestGetTags(t *testing.T) { } for _, tag := range tags { - err = createTag(ctx, gormDB, &tag) + err = CreateTag(ctx, gormDB, &tag) if err != nil { t.Fatal(err) } diff --git a/internal/postgres/user.go b/internal/postgres/user.go index fed56f9..91282d2 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -31,7 +31,7 @@ func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID string) error { return nil } -func CreateUserNodeWithSourceRelation(ctx context.Context, db *gorm.DB, anthroveUserID string, sourceDomain string, userID string, username string) error { +func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUserID string, sourceDomain string, userID string, username string) error { if anthroveUserID == "" || username == "" || userID == "" { return fmt.Errorf("anthroveUserID cannot be empty") @@ -143,19 +143,23 @@ func GetUserSourceLinks(ctx context.Context, db *gorm.DB, anthroveUserID models. return userSourceMap, nil } -func GetSpecifiedUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.UserSource, error) { - if anthroveUserID == "" || sourceDisplayName == "" { - return nil, fmt.Errorf("anthroveUserID or sourceDisplayName is empty") +func GetUserSourceBySourceID(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceID string) (map[string]models.UserSource, error) { + if anthroveUserID == "" { + return nil, fmt.Errorf("anthroveUserID cannot be empty") + } + + if sourceID == "" { + return nil, fmt.Errorf("sourceID cannot be empty") } var userSources []models.UserSource userSourceMap := make(map[string]models.UserSource) - err := db.WithContext(ctx).Model(&models.UserSource{}).InnerJoins("Source", db.Where("display_name = ?", sourceDisplayName)).Where("user_id = ?", string(anthroveUserID)).First(&userSources).Error + err := db.WithContext(ctx).Model(&models.UserSource{}).InnerJoins("Source", db.Where("id = ?", sourceID)).Where("user_id = ?", string(anthroveUserID)).First(&userSources).Error if err != nil { log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - "source_display_name": sourceDisplayName, + "anthrove_user_id": anthroveUserID, + "source_id": sourceID, }).Error("database: failed to get specified user source link") return nil, err } @@ -182,8 +186,8 @@ func GetSpecifiedUserSourceLink(ctx context.Context, db *gorm.DB, anthroveUserID } log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - "source_display_name": sourceDisplayName, + "anthrove_user_id": anthroveUserID, + "source_id": sourceID, }).Trace("database: got specified user source link") return userSourceMap, nil @@ -210,7 +214,7 @@ func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]string, error) { return userIDs, nil } -func GetUserFavoriteNodeWithPagination(ctx context.Context, db *gorm.DB, anthroveUserID string, skip int, limit int) (*models.FavoriteList, error) { +func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUserID string, skip int, limit int) (*models.FavoriteList, error) { var userFavorites []models.UserFavorite var favoritePosts []models.Post @@ -249,7 +253,7 @@ func GetUserFavoriteNodeWithPagination(ctx context.Context, db *gorm.DB, anthrov return &models.FavoriteList{Posts: favoritePosts}, nil } -func GetUserTagNodeWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { +func GetUserTagWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { var userFavorites []models.UserFavorite err := db.WithContext(ctx).Where("user_id = ?", string(anthroveUserID)).Find(&userFavorites).Error if err != nil { diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index cae2b0c..3adee0f 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -76,7 +76,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { Domain: "e621.net", Icon: "icon.e621.net", } - err = CreateSourceNode(ctx, gormDB, source) + err = CreateSource(ctx, gormDB, source) if err != nil { t.Fatal(err) } @@ -170,8 +170,8 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := CreateUserNodeWithSourceRelation(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.sourceDomain, tt.args.userID, tt.args.username); (err != nil) != tt.wantErr { - t.Errorf("CreateUserNodeWithSourceRelation() error = %v, wantErr %v", err, tt.wantErr) + if err := CreateUserWithRelationToSource(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.sourceDomain, tt.args.userID, tt.args.username); (err != nil) != tt.wantErr { + t.Errorf("CreateUserWithRelationToSource() error = %v, wantErr %v", err, tt.wantErr) } }) } @@ -232,7 +232,7 @@ func TestGetAllAnthroveUserIDs(t *testing.T) { } } -func TestGetSpecifiedUserSourceLink(t *testing.T) { +func TestGetUserSourceBySourceID(t *testing.T) { // Setup trow away container ctx := context.Background() container, gormDB, err := test.StartPostgresContainer(ctx) @@ -254,26 +254,27 @@ func TestGetSpecifiedUserSourceLink(t *testing.T) { } source := &models.Source{ + BaseModel: models.BaseModel{ID: expectedResult["e621"].Source.ID}, DisplayName: expectedResult["e621"].Source.DisplayName, Domain: expectedResult["e621"].Source.Domain, } - err = CreateSourceNode(ctx, gormDB, source) + err = CreateSource(ctx, gormDB, source) if err != nil { t.Fatal(err) } - err = CreateUserNodeWithSourceRelation(ctx, gormDB, "1", source.Domain, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) + err = CreateUserWithRelationToSource(ctx, gormDB, "1", source.Domain, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) if err != nil { t.Fatal(err) } // Test type args struct { - ctx context.Context - db *gorm.DB - anthroveUserID models.AnthroveUserID - sourceDisplayName string + ctx context.Context + db *gorm.DB + anthroveUserID models.AnthroveUserID + sourceID string } tests := []struct { name string @@ -282,45 +283,45 @@ func TestGetSpecifiedUserSourceLink(t *testing.T) { wantErr bool }{ { - name: "Test 1: Valid AnthroveUserID and SourceDisplayName", + name: "Test 1: Valid AnthroveUserID and sourceID", args: args{ - ctx: ctx, - db: gormDB, - anthroveUserID: "1", - sourceDisplayName: "e621", + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + sourceID: source.ID, }, want: expectedResult, wantErr: false, }, { - name: "Test 2: Invalid AnthroveUserID and valid SourceDisplayName", + name: "Test 2: Invalid AnthroveUserID and valid sourceID", args: args{ - ctx: ctx, - db: gormDB, - anthroveUserID: "22", - sourceDisplayName: "e621", + ctx: ctx, + db: gormDB, + anthroveUserID: "22", + sourceID: source.ID, }, want: nil, wantErr: true, }, { - name: "Test 3: Valid AnthroveUserID and invalid SourceDisplayName", + name: "Test 3: Valid AnthroveUserID and invalid sourceID", args: args{ - ctx: ctx, - db: gormDB, - anthroveUserID: "1", - sourceDisplayName: "fa", + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + sourceID: "fa", }, want: nil, wantErr: true, }, { - name: "Test 4: No AnthroveUserID and Valid SourceDisplayName", + name: "Test 4: No AnthroveUserID and Valid sourceID", args: args{ - ctx: ctx, - db: gormDB, - anthroveUserID: "", - sourceDisplayName: "e621", + ctx: ctx, + db: gormDB, + anthroveUserID: "", + sourceID: source.ID, }, want: nil, wantErr: true, @@ -328,10 +329,10 @@ func TestGetSpecifiedUserSourceLink(t *testing.T) { { name: "Test 5: Valid AnthroveUserID and No SourceDisplayName", args: args{ - ctx: ctx, - db: gormDB, - anthroveUserID: "1", - sourceDisplayName: "", + ctx: ctx, + db: gormDB, + anthroveUserID: "1", + sourceID: "", }, want: nil, wantErr: true, @@ -339,10 +340,10 @@ func TestGetSpecifiedUserSourceLink(t *testing.T) { { name: "Test 6: No AnthroveUserID and No SourceDisplayName", args: args{ - ctx: ctx, - db: gormDB, - anthroveUserID: "", - sourceDisplayName: "", + ctx: ctx, + db: gormDB, + anthroveUserID: "", + sourceID: "", }, want: nil, wantErr: true, @@ -350,18 +351,17 @@ func TestGetSpecifiedUserSourceLink(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := GetSpecifiedUserSourceLink(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.sourceDisplayName) + got, err := GetUserSourceBySourceID(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.sourceID) if (err != nil) != tt.wantErr { - t.Errorf("GetSpecifiedUserSourceLink() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetUserSourceBySourceID() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetSpecifiedUserSourceLink() got = %v, want %v", got, tt.want) + t.Errorf("GetUserSourceBySourceID() got = %v, want %v", got, tt.want) } }) } } - func TestGetUserFavoriteNodeWithPagination(t *testing.T) { // Setup trow away containert ctx := context.Background() @@ -420,7 +420,7 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { if err != nil { t.Fatal(err) } - err = EstablishUserToPostLink(ctx, gormDB, "1", expectedResultPost.ID) + err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", expectedResultPost.ID) if err != nil { t.Fatal(err) } @@ -479,13 +479,13 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := GetUserFavoriteNodeWithPagination(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.skip, tt.args.limit) + got, err := GetUserFavoriteWithPagination(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.skip, tt.args.limit) if (err != nil) != tt.wantErr { - t.Errorf("GetUserFavoriteNodeWithPagination() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetUserFavoriteWithPagination() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetUserFavoriteNodeWithPagination() got = %v, want %v", got, tt.want) + t.Errorf("GetUserFavoriteWithPagination() got = %v, want %v", got, tt.want) } }) } @@ -539,7 +539,7 @@ func TestGetUserFavoritesCount(t *testing.T) { if err != nil { t.Fatal(err) } - err = EstablishUserToPostLink(ctx, gormDB, "1", post.ID) + err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", post.ID) if err != nil { t.Fatal(err) } @@ -616,7 +616,7 @@ func TestGetUserSourceLinks(t *testing.T) { DisplayName: "e621", Domain: "e621.net", } - err = CreateSourceNode(ctx, gormDB, eSource) + err = CreateSource(ctx, gormDB, eSource) if err != nil { t.Fatal(err) } @@ -625,7 +625,7 @@ func TestGetUserSourceLinks(t *testing.T) { DisplayName: "fa", Domain: "fa.net", } - err = CreateSourceNode(ctx, gormDB, faSource) + err = CreateSource(ctx, gormDB, faSource) if err != nil { t.Fatal(err) } @@ -648,11 +648,11 @@ func TestGetUserSourceLinks(t *testing.T) { }, } - err = CreateUserNodeWithSourceRelation(ctx, gormDB, "1", eSource.Domain, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) + err = CreateUserWithRelationToSource(ctx, gormDB, "1", eSource.Domain, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) if err != nil { t.Fatal(err) } - err = CreateUserNodeWithSourceRelation(ctx, gormDB, "1", faSource.Domain, expectedResult["fa"].UserID, expectedResult["fa"].AccountUsername) + err = CreateUserWithRelationToSource(ctx, gormDB, "1", faSource.Domain, expectedResult["fa"].UserID, expectedResult["fa"].AccountUsername) if err != nil { t.Fatal(err) } @@ -720,7 +720,7 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { if err != nil { t.Fatal(err) } - err = EstablishUserToPostLink(ctx, gormDB, "1", post.ID) + err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", post.ID) if err != nil { t.Fatal(err) } @@ -733,7 +733,7 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { } for i, tag := range tags { - err = CreateTagNodeWitRelation(ctx, gormDB, posts[i].ID, &tag) + err = CreateTagAndReferenceToPost(ctx, gormDB, posts[i].ID, &tag) if err != nil { t.Fatal(err) } @@ -788,13 +788,13 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := GetUserTagNodeWitRelationToFavedPosts(tt.args.ctx, tt.args.db, tt.args.anthroveUserID) + got, err := GetUserTagWitRelationToFavedPosts(tt.args.ctx, tt.args.db, tt.args.anthroveUserID) if (err != nil) != tt.wantErr { - t.Errorf("GetUserTagNodeWitRelationToFavedPosts() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetUserTagWitRelationToFavedPosts() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetUserTagNodeWitRelationToFavedPosts() got = %v, want %v", got, tt.want) + t.Errorf("GetUserTagWitRelationToFavedPosts() got = %v, want %v", got, tt.want) } }) } diff --git a/pkg/database/database.go b/pkg/database/database.go index 76269bf..f0c74f0 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -9,26 +9,26 @@ type OtterSpace interface { // Connect establishes a connection to the database. Connect(ctx context.Context, endpoint string, username string, password string, database string, port int, ssl string, timezone string) error - // AddUserWithRelationToSource adds a user with a relation to a source. - AddUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error + // CreateUserWithRelationToSource adds a user with a relation to a source. + CreateUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error - // AddSource adds a new source to the database. - AddSource(ctx context.Context, anthroveSource *models.Source) error + // CreateSource adds a new source to the database. + CreateSource(ctx context.Context, anthroveSource *models.Source) error - // AddPost adds a new post to the database. - AddPost(ctx context.Context, anthrovePost *models.Post) error + // CreatePost adds a new post to the database. + CreatePost(ctx context.Context, anthrovePost *models.Post) error - // AddTagWithRelationToPost adds a tag with a relation to a post. - AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error + // CreateTagAndReferenceToPost adds a tag with a relation to a post. + CreateTagAndReferenceToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error - // LinkPostWithSource links a post with a source. - LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *models.PostReference) error + // CreateReferenceBetweenPostAndSource links a post with a source. + CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *models.PostReference) error - // LinkUserWithPost links a user with a post. - LinkUserWithPost(ctx context.Context, anthroveUser *models.User, anthrovePost *models.Post) error + // CreateReferenceBetweenUserAndPost links a user with a post. + CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUser *models.User, anthrovePost *models.Post) error - // CheckUserPostLink checks if a user-post link exists. - CheckUserPostLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) + // CheckReferenceBetweenUserAndPost checks if a user-post link exists. + CheckReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) // GetPostByAnthroveID retrieves a post by its Anthrove ID. GetPostByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, error) @@ -39,26 +39,26 @@ type OtterSpace interface { // GetPostBySourceID retrieves a post by its source ID. GetPostBySourceID(ctx context.Context, sourcePostID string) (*models.Post, error) - // GetUserFavoriteCount retrieves the count of a user's favorites. - GetUserFavoriteCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) + // GetUserFavoritesCount retrieves the count of a user's favorites. + GetUserFavoritesCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) // GetUserSourceLinks retrieves the source links of a user. GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) - // GetSpecifiedUserSourceLink retrieves a specified source link of a user. - GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.UserSource, error) + // GetUserSourceBySourceID retrieves a specified source link of a user. + GetUserSourceBySourceID(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID string) (map[string]models.UserSource, error) // GetAllAnthroveUserIDs retrieves all Anthrove user IDs. GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) - // GetUserFavoritePostsWithPagination retrieves a user's favorite posts with pagination. - GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) + // GetUserFavoriteWithPagination retrieves a user's favorite posts with pagination. + GetUserFavoriteWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) - // GetUserTagsTroughFavedPosts retrieves a user's tags through their favorited posts. - GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) + // GetUserTagWitRelationToFavedPosts retrieves a user's tags through their favorited posts. + GetUserTagWitRelationToFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) // GetAllTags retrieves all tags. - GetAllTags(ctx context.Context) ([]models.TagsWithFrequency, error) + GetAllTags(ctx context.Context) ([]models.Tag, error) // GetAllSources retrieves all sources. GetAllSources(ctx context.Context) ([]models.Source, error) diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 0cfc1bd..3503deb 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -64,32 +64,32 @@ func (p *postgresqlConnection) Connect(_ context.Context, endpoint string, usern return nil } -func (p *postgresqlConnection) AddUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error { - return postgres.CreateUserNodeWithSourceRelation(ctx, p.db, anthroveUserID, sourceDomain, userID, userID) +func (p *postgresqlConnection) CreateUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error { + return postgres.CreateUserWithRelationToSource(ctx, p.db, anthroveUserID, sourceDomain, userID, userID) } -func (p *postgresqlConnection) AddSource(ctx context.Context, anthroveSource *models.Source) error { - return postgres.CreateSourceNode(ctx, p.db, anthroveSource) +func (p *postgresqlConnection) CreateSource(ctx context.Context, anthroveSource *models.Source) error { + return postgres.CreateSource(ctx, p.db, anthroveSource) } -func (p *postgresqlConnection) AddPost(ctx context.Context, anthrovePost *models.Post) error { +func (p *postgresqlConnection) CreatePost(ctx context.Context, anthrovePost *models.Post) error { return postgres.CreatePost(ctx, p.db, anthrovePost) } -func (p *postgresqlConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error { - return postgres.CreateTagNodeWitRelation(ctx, p.db, anthrovePostID, anthroveTag) +func (p *postgresqlConnection) CreateTagAndReferenceToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error { + return postgres.CreateTagAndReferenceToPost(ctx, p.db, anthrovePostID, anthroveTag) } -func (p *postgresqlConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain string, anthrovePostRelationship *models.PostReference) error { - return postgres.EstablishAnthrovePostToSourceLink(ctx, p.db, anthrovePostID, sourceDomain, anthrovePostRelationship) +func (p *postgresqlConnection) CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain string, anthrovePostRelationship *models.PostReference) error { + return postgres.CreateReferenceBetweenPostAndSource(ctx, p.db, anthrovePostID, sourceDomain, anthrovePostRelationship) } -func (p *postgresqlConnection) LinkUserWithPost(ctx context.Context, anthroveUser *models.User, anthrovePost *models.Post) error { - return postgres.EstablishUserToPostLink(ctx, p.db, anthroveUser.ID, anthrovePost.ID) +func (p *postgresqlConnection) CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUser *models.User, anthrovePost *models.Post) error { + return postgres.CreateReferenceBetweenUserAndPost(ctx, p.db, anthroveUser.ID, anthrovePost.ID) } -func (p *postgresqlConnection) CheckUserPostLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) { - return postgres.CheckUserToPostLink(ctx, p.db, anthroveUserID, models.AnthrovePostID(sourcePostID)) +func (p *postgresqlConnection) CheckReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) { + return postgres.CheckReferenceBetweenUserAndPost(ctx, p.db, anthroveUserID, models.AnthrovePostID(sourcePostID)) } func (p *postgresqlConnection) GetPostByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, error) { @@ -104,7 +104,7 @@ func (p *postgresqlConnection) GetPostBySourceID(ctx context.Context, sourcePost return postgres.GetPostBySourceID(ctx, p.db, sourcePostID) } -func (p *postgresqlConnection) GetUserFavoriteCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) { +func (p *postgresqlConnection) GetUserFavoritesCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) { return postgres.GetUserFavoritesCount(ctx, p.db, anthroveUserID) } @@ -112,7 +112,7 @@ func (p *postgresqlConnection) GetUserSourceLinks(ctx context.Context, anthroveU return postgres.GetUserSourceLinks(ctx, p.db, anthroveUserID) } -func (p *postgresqlConnection) GetSpecifiedUserSourceLink(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.UserSource, error) { +func (p *postgresqlConnection) GetUserSourceBySourceID(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.UserSource, error) { return postgres.GetSpecifiedUserSourceLink(ctx, p.db, anthroveUserID, sourceDisplayName) } @@ -120,24 +120,24 @@ func (p *postgresqlConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]mod return postgres.GetAllAnthroveUserIDs(ctx, p.db) } -func (p *postgresqlConnection) GetUserFavoritePostsWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) { - return postgres.GetUserFavoriteNodeWithPagination(ctx, p.db, anthroveUserID, skip, limit) +func (p *postgresqlConnection) GetUserFavoriteWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) { + return postgres.GetUserFavoriteWithPagination(ctx, p.db, anthroveUserID, skip, limit) } -func (p *postgresqlConnection) GetUserTagsTroughFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { - return postgres.GetUserTagNodeWitRelationToFavedPosts(ctx, p.db, anthroveUserID) +func (p *postgresqlConnection) GetUserTagWitRelationToFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { + return postgres.GetUserTagWitRelationToFavedPosts(ctx, p.db, anthroveUserID) } -func (p *postgresqlConnection) GetAllTags(ctx context.Context) ([]models.TagsWithFrequency, error) { +func (p *postgresqlConnection) GetAllTags(ctx context.Context) ([]models.Tag, error) { return postgres.GetTags(ctx, p.db) } func (p *postgresqlConnection) GetAllSources(ctx context.Context) ([]models.Source, error) { - return postgres.GetAllSourceNodes(ctx, p.db) + return postgres.GetAllSource(ctx, p.db) } func (p *postgresqlConnection) GetSourceByURL(ctx context.Context, sourceUrl string) (*models.Source, error) { - return postgres.GetSourceNodesByURL(ctx, p.db, sourceUrl) + return postgres.GetSourceByURL(ctx, p.db, sourceUrl) } func (p *postgresqlConnection) migrateDatabase(connectionString string) error { -- 2.45.1 From b0d98d842f2e37c21b7886514883a035c10626cc Mon Sep 17 00:00:00 2001 From: soxx Date: Sun, 23 Jun 2024 22:35:46 +0200 Subject: [PATCH 068/124] refactor(postgres): renamed function names and fixed tests and other issues Signed-off-by: soxx --- internal/postgres/post.go | 6 +-- internal/postgres/post_test.go | 18 ++++---- internal/postgres/relationships.go | 10 ++--- internal/postgres/relationships_test.go | 22 ++++----- internal/postgres/source.go | 8 ++-- internal/postgres/source_test.go | 8 ++-- internal/postgres/tag.go | 2 +- internal/postgres/tag_test.go | 6 +-- internal/postgres/user.go | 48 +++++++++++--------- internal/postgres/user_test.go | 60 +++++++++++++------------ pkg/database/database.go | 20 ++++----- pkg/database/postgres.go | 32 ++++++------- pkg/models/const.go | 5 ++- pkg/models/orm.go | 6 +++ 14 files changed, 135 insertions(+), 116 deletions(-) diff --git a/internal/postgres/post.go b/internal/postgres/post.go index 079be3d..2dde49a 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -23,7 +23,7 @@ func CreatePost(ctx context.Context, db *gorm.DB, anthrovePost *models.Post) err return nil } -func GetPostByAnthroveID(ctx context.Context, db *gorm.DB, anthrovePostID string) (*models.Post, error) { +func GetPostByAnthroveID(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID) (*models.Post, error) { if anthrovePostID == "" { return nil, fmt.Errorf("anthrovePostID is required") } @@ -37,7 +37,7 @@ func GetPostByAnthroveID(ctx context.Context, db *gorm.DB, anthrovePostID string return &post, nil } -func GetPostBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (*models.Post, error) { +func GetPostByURL(ctx context.Context, db *gorm.DB, sourceURL string) (*models.Post, error) { var post models.Post err := db.WithContext(ctx).Raw(`SELECT p.id AS id, p.rating as rating FROM "Post" AS p INNER JOIN "PostReference" AS pr ON p.id = pr.post_id AND pr.url = $1 LIMIT 1`, sourceURL).First(&post).Error @@ -51,7 +51,7 @@ func GetPostBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (*mo return &post, nil } -func GetPostBySourceID(ctx context.Context, db *gorm.DB, sourceID string) (*models.Post, error) { +func GetPostBySourceID(ctx context.Context, db *gorm.DB, sourceID models.AnthroveSourceID) (*models.Post, error) { var post models.Post err := db.WithContext(ctx).Raw(`SELECT p.id AS id, p.rating as rating FROM "Post" AS p INNER JOIN "PostReference" AS pr ON p.id = pr.post_id AND pr.source_id = $1 LIMIT 1`, sourceID).First(&post).Error diff --git a/internal/postgres/post_test.go b/internal/postgres/post_test.go index 098fe2b..cf2ebc4 100644 --- a/internal/postgres/post_test.go +++ b/internal/postgres/post_test.go @@ -99,7 +99,7 @@ func TestGetPostByAnthroveID(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - anthrovePostID string + anthrovePostID models.AnthrovePostID } tests := []struct { name string @@ -112,7 +112,7 @@ func TestGetPostByAnthroveID(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthrovePostID: post.ID, + anthrovePostID: models.AnthrovePostID(post.ID), }, want: post, wantErr: false, @@ -186,7 +186,7 @@ func TestGetPostBySourceURL(t *testing.T) { t.Fatal("Could not create source", err) } - err = CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, source.Domain) + err = CreateReferenceBetweenPostAndSource(ctx, gormDB, models.AnthrovePostID(post.ID), models.AnthroveSourceDomain(source.Domain)) if err != nil { t.Fatal("Could not create source reference", err) } @@ -236,13 +236,13 @@ func TestGetPostBySourceURL(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := GetPostBySourceURL(tt.args.ctx, tt.args.db, tt.args.sourceURL) + got, err := GetPostByURL(tt.args.ctx, tt.args.db, tt.args.sourceURL) if (err != nil) != tt.wantErr { - t.Errorf("GetPostBySourceURL() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetPostByURL() error = %v, wantErr %v", err, tt.wantErr) return } if !checkPost(got, tt.want) { - t.Errorf("GetPostBySourceURL() got = %v, want %v", got, tt.want) + t.Errorf("GetPostByURL() got = %v, want %v", got, tt.want) } }) } @@ -283,7 +283,7 @@ func TestGetPostBySourceID(t *testing.T) { t.Fatal("Could not create source", err) } - err = CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, source.Domain) + err = CreateReferenceBetweenPostAndSource(ctx, gormDB, models.AnthrovePostID(post.ID), models.AnthroveSourceDomain(source.Domain)) if err != nil { t.Fatal("Could not create source reference", err) } @@ -292,7 +292,7 @@ func TestGetPostBySourceID(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - sourceID string + sourceID models.AnthroveSourceID } tests := []struct { @@ -306,7 +306,7 @@ func TestGetPostBySourceID(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - sourceID: source.ID, + sourceID: models.AnthroveSourceID(source.ID), }, want: post, wantErr: false, diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index cade964..5c268f8 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" ) -func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthrovePostID string, sourceDomain string) error { +func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain) error { var source models.Source var err error @@ -19,9 +19,9 @@ func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthr // Establish the relationship err = db.WithContext(ctx).Create(models.PostReference{ - PostID: anthrovePostID, + PostID: string(anthrovePostID), SourceID: source.ID, - URL: sourceDomain, + URL: string(sourceDomain), }).Error if err != nil { @@ -36,7 +36,7 @@ func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthr return nil } -func CreateReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthroveUserID string, anthrovePostID string) error { +func CreateReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error { userFavorite := models.UserFavorite{ UserID: string(anthroveUserID), PostID: string(anthrovePostID), @@ -55,7 +55,7 @@ func CreateReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthrov return nil } -func CheckReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthroveUserID string, anthrovePostID string) (bool, error) { +func CheckReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) (bool, error) { var count int64 err := db.WithContext(ctx).Model(&models.UserFavorite{}).Where("user_id = ? AND post_id = ?", string(anthroveUserID), string(anthrovePostID)).Count(&count).Error if err != nil { diff --git a/internal/postgres/relationships_test.go b/internal/postgres/relationships_test.go index 4d49f65..cc763a0 100644 --- a/internal/postgres/relationships_test.go +++ b/internal/postgres/relationships_test.go @@ -37,7 +37,7 @@ func TestCheckUserToPostLink(t *testing.T) { t.Fatal(err) } - err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", post.ID) + err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", models.AnthrovePostID(post.ID)) if err != nil { t.Fatal(err) } @@ -46,8 +46,8 @@ func TestCheckUserToPostLink(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - anthroveUserID string - anthrovePostID string + anthroveUserID models.AnthroveUserID + anthrovePostID models.AnthrovePostID } tests := []struct { name string @@ -61,7 +61,7 @@ func TestCheckUserToPostLink(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "1", - anthrovePostID: post.ID, + anthrovePostID: models.AnthrovePostID(post.ID), }, want: true, wantErr: false, @@ -83,7 +83,7 @@ func TestCheckUserToPostLink(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "123", - anthrovePostID: post.ID, + anthrovePostID: models.AnthrovePostID(post.ID), }, want: false, wantErr: false, @@ -150,8 +150,8 @@ func TestEstablishAnthrovePostToSourceLink(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - anthrovePostID string - sourceDomain string + anthrovePostID models.AnthrovePostID + sourceDomain models.AnthroveSourceDomain anthrovePostRelationship *models.PostReference } tests := []struct { @@ -164,7 +164,7 @@ func TestEstablishAnthrovePostToSourceLink(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthrovePostID: post.ID, + anthrovePostID: models.AnthrovePostID(post.ID), sourceDomain: "e621.net", }, wantErr: false, @@ -240,8 +240,8 @@ func TestEstablishUserToPostLink(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - anthroveUserID string - anthrovePostID string + anthroveUserID models.AnthroveUserID + anthrovePostID models.AnthrovePostID } tests := []struct { name string @@ -254,7 +254,7 @@ func TestEstablishUserToPostLink(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "1", - anthrovePostID: post.ID, + anthrovePostID: models.AnthrovePostID(post.ID), }, wantErr: false, }, diff --git a/internal/postgres/source.go b/internal/postgres/source.go index ec889fd..da13fc3 100644 --- a/internal/postgres/source.go +++ b/internal/postgres/source.go @@ -48,15 +48,15 @@ func GetAllSource(ctx context.Context, db *gorm.DB) ([]models.Source, error) { return sources, nil } -// GetSourceByURL returns the first source it finds based on the domain -func GetSourceByURL(ctx context.Context, db *gorm.DB, domain string) (*models.Source, error) { +// GetSourceByDomain returns the first source it finds based on the domain +func GetSourceByDomain(ctx context.Context, db *gorm.DB, sourceDomain models.AnthroveSourceDomain) (*models.Source, error) { var sources models.Source - if domain == "" { + if sourceDomain == "" { return nil, fmt.Errorf("domain is required") } - result := db.WithContext(ctx).Where("domain = ?", domain).First(&sources) + result := db.WithContext(ctx).Where("domain = ?", sourceDomain).First(&sources) if result.Error != nil { return nil, result.Error diff --git a/internal/postgres/source_test.go b/internal/postgres/source_test.go index a6d7863..80c0dc8 100644 --- a/internal/postgres/source_test.go +++ b/internal/postgres/source_test.go @@ -174,7 +174,7 @@ func TestGetSourceNodesByURL(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - domain string + domain models.AnthroveSourceDomain } tests := []struct { name string @@ -215,13 +215,13 @@ func TestGetSourceNodesByURL(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := GetSourceByURL(tt.args.ctx, tt.args.db, tt.args.domain) + got, err := GetSourceByDomain(tt.args.ctx, tt.args.db, tt.args.domain) if (err != nil) != tt.wantErr { - t.Errorf("GetSourceByURL() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetSourceByDomain() error = %v, wantErr %v", err, tt.wantErr) return } if !checkSourceNode(got, tt.want) { - t.Errorf("GetSourceByURL() got = %v, want %v", got, tt.want) + t.Errorf("GetSourceByDomain() got = %v, want %v", got, tt.want) } }) } diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 4213b28..a20b352 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -24,7 +24,7 @@ func CreateTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { return nil } -func CreateTagAndReferenceToPost(ctx context.Context, db *gorm.DB, PostID string, tag *models.Tag) error { +func CreateTagAndReferenceToPost(ctx context.Context, db *gorm.DB, PostID models.AnthrovePostID, tag *models.Tag) error { if PostID == "" { return fmt.Errorf("PostID is empty") diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index d83d760..bc94c77 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -41,7 +41,7 @@ func TestCreateTagNodeWitRelation(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - PostID string + PostID models.AnthrovePostID tag *models.Tag } tests := []struct { @@ -54,7 +54,7 @@ func TestCreateTagNodeWitRelation(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - PostID: post.ID, + PostID: models.AnthrovePostID(post.ID), tag: tag, }, wantErr: false, @@ -64,7 +64,7 @@ func TestCreateTagNodeWitRelation(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - PostID: post.ID, + PostID: models.AnthrovePostID(post.ID), tag: nil, }, wantErr: true, diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 91282d2..1b4e38f 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -8,7 +8,7 @@ import ( "gorm.io/gorm" ) -func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID string) error { +func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) error { if anthroveUserID == "" { return fmt.Errorf("anthroveUserID cannot be empty") @@ -31,51 +31,59 @@ func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID string) error { return nil } -func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUserID string, sourceDomain string, userID string, username string) error { +func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, accountId string, accountUsername string) error { - if anthroveUserID == "" || username == "" || userID == "" { + if anthroveUserID == "" { return fmt.Errorf("anthroveUserID cannot be empty") } + if accountId == "" { + return fmt.Errorf("account_id cannot be empty") + } + + if accountUsername == "" { + return fmt.Errorf("account_username cannot be empty") + } + err := CreateUser(ctx, db, anthroveUserID) if err != nil { return err } source := models.Source{ - Domain: sourceDomain, + BaseModel: models.BaseModel{ID: string(sourceID)}, } if err := db.WithContext(ctx).Where(&source).First(&source).Error; err != nil { log.WithFields(log.Fields{ - "source_domain": sourceDomain, + "source_id": sourceID, }).Error("database: failed to find source") return err } userSource := models.UserSource{ - User: models.User{BaseModel: models.BaseModel{ID: anthroveUserID}}, + User: models.User{BaseModel: models.BaseModel{ID: string(anthroveUserID)}}, SourceID: source.ID, - AccountUsername: username, - AccountID: userID, - UserID: anthroveUserID, + AccountUsername: accountUsername, + AccountID: accountId, + UserID: string(anthroveUserID), } if err := db.WithContext(ctx).FirstOrCreate(&userSource).Error; err != nil { log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, - "source_domain": sourceDomain, - "account_username": username, - "account_id": userID, + "source_id": sourceID, + "account_username": accountUsername, + "account_id": accountId, }).Error("database: failed to create user-source relationship") return err } log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, - "source_domain": sourceDomain, - "account_username": username, - "account_id": userID, + "source_id": sourceID, + "account_username": accountUsername, + "account_id": accountId, }).Trace("database: created user-source relationship") return nil @@ -143,7 +151,7 @@ func GetUserSourceLinks(ctx context.Context, db *gorm.DB, anthroveUserID models. return userSourceMap, nil } -func GetUserSourceBySourceID(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceID string) (map[string]models.UserSource, error) { +func GetUserSourceBySourceID(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID) (map[string]models.UserSource, error) { if anthroveUserID == "" { return nil, fmt.Errorf("anthroveUserID cannot be empty") } @@ -193,9 +201,9 @@ func GetUserSourceBySourceID(ctx context.Context, db *gorm.DB, anthroveUserID mo return userSourceMap, nil } -func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]string, error) { +func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveUserID, error) { var users []models.User - var userIDs []string + var userIDs []models.AnthroveUserID err := db.WithContext(ctx).Model(&models.User{}).Find(&users).Error if err != nil { @@ -204,7 +212,7 @@ func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]string, error) { } for _, user := range users { - userIDs = append(userIDs, user.ID) + userIDs = append(userIDs, models.AnthroveUserID(user.ID)) } log.WithFields(log.Fields{ @@ -214,7 +222,7 @@ func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]string, error) { return userIDs, nil } -func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUserID string, skip int, limit int) (*models.FavoriteList, error) { +func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) { var userFavorites []models.UserFavorite var favoritePosts []models.Post diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index 3adee0f..6a701da 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -25,7 +25,7 @@ func TestCreateUser(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - anthroveUserID string + anthroveUserID models.AnthroveUserID } tests := []struct { name string @@ -72,6 +72,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { // Setup Test source := &models.Source{ + BaseModel: models.BaseModel{ID: fmt.Sprintf("%025s", "1")}, DisplayName: "e621", Domain: "e621.net", Icon: "icon.e621.net", @@ -85,8 +86,8 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - anthroveUserID string - sourceDomain string + anthroveUserID models.AnthroveUserID + sourceID models.AnthroveSourceID userID string username string } @@ -96,24 +97,24 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { wantErr bool }{ { - name: "Test 1: Valid anthroveUserID, sourceDomain, userID, username", + name: "Test 1: Valid anthroveUserID, sourceID, userID, username", args: args{ ctx: ctx, db: gormDB, anthroveUserID: "1", - sourceDomain: source.Domain, + sourceID: models.AnthroveSourceID(source.ID), userID: "e1", username: "marius", }, wantErr: false, }, { - name: "Test 2: Invalid anthroveUserID, valid sourceDomain, userID, username", + name: "Test 2: Invalid anthroveUserID, valid sourceID, userID, username", args: args{ ctx: ctx, db: gormDB, anthroveUserID: "2", - sourceDomain: source.Domain, + sourceID: models.AnthroveSourceID(source.ID), userID: "e1", username: "marius", }, @@ -125,19 +126,19 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "", - sourceDomain: source.Domain, + sourceID: models.AnthroveSourceID(source.ID), userID: "e1", username: "marius", }, wantErr: true, }, { - name: "Test 4: invalid sourceDomain", + name: "Test 4: invalid sourceID", args: args{ ctx: ctx, db: gormDB, anthroveUserID: "1", - sourceDomain: "fa.net", + sourceID: "fa.net", userID: "e1", username: "marius", }, @@ -149,7 +150,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "1", - sourceDomain: source.Domain, + sourceID: models.AnthroveSourceID(source.ID), userID: "", username: "marius", }, @@ -161,7 +162,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "1", - sourceDomain: source.Domain, + sourceID: models.AnthroveSourceID(source.ID), userID: "aa", username: "", }, @@ -170,7 +171,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := CreateUserWithRelationToSource(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.sourceDomain, tt.args.userID, tt.args.username); (err != nil) != tt.wantErr { + if err := CreateUserWithRelationToSource(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.sourceID, tt.args.userID, tt.args.username); (err != nil) != tt.wantErr { t.Errorf("CreateUserWithRelationToSource() error = %v, wantErr %v", err, tt.wantErr) } }) @@ -188,7 +189,7 @@ func TestGetAllAnthroveUserIDs(t *testing.T) { // Setup Test - users := []string{"1", "2", "3"} + users := []models.AnthroveUserID{"1", "2", "3"} for _, user := range users { err = CreateUser(ctx, gormDB, user) @@ -205,7 +206,7 @@ func TestGetAllAnthroveUserIDs(t *testing.T) { tests := []struct { name string args args - want []string + want []models.AnthroveUserID wantErr bool }{ { @@ -264,7 +265,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { t.Fatal(err) } - err = CreateUserWithRelationToSource(ctx, gormDB, "1", source.Domain, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) + err = CreateUserWithRelationToSource(ctx, gormDB, "1", models.AnthroveSourceID(expectedResult["e621"].SourceID), expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) if err != nil { t.Fatal(err) } @@ -274,7 +275,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { ctx context.Context db *gorm.DB anthroveUserID models.AnthroveUserID - sourceID string + sourceID models.AnthroveSourceID } tests := []struct { name string @@ -288,7 +289,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "1", - sourceID: source.ID, + sourceID: models.AnthroveSourceID(source.ID), }, want: expectedResult, wantErr: false, @@ -299,7 +300,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "22", - sourceID: source.ID, + sourceID: models.AnthroveSourceID(source.ID), }, want: nil, wantErr: true, @@ -321,7 +322,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "", - sourceID: source.ID, + sourceID: models.AnthroveSourceID(source.ID), }, want: nil, wantErr: true, @@ -362,6 +363,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { }) } } + func TestGetUserFavoriteNodeWithPagination(t *testing.T) { // Setup trow away containert ctx := context.Background() @@ -420,7 +422,7 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { if err != nil { t.Fatal(err) } - err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", expectedResultPost.ID) + err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", models.AnthrovePostID(expectedResultPost.ID)) if err != nil { t.Fatal(err) } @@ -430,7 +432,7 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { type args struct { ctx context.Context db *gorm.DB - anthroveUserID string + anthroveUserID models.AnthroveUserID skip int limit int } @@ -492,7 +494,7 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { } func TestGetUserFavoritesCount(t *testing.T) { - // Setup trow away containert + // Setup trow away container ctx := context.Background() container, gormDB, err := test.StartPostgresContainer(ctx) if err != nil { @@ -539,7 +541,7 @@ func TestGetUserFavoritesCount(t *testing.T) { if err != nil { t.Fatal(err) } - err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", post.ID) + err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", models.AnthrovePostID(post.ID)) if err != nil { t.Fatal(err) } @@ -613,6 +615,7 @@ func TestGetUserSourceLinks(t *testing.T) { // Setup Test eSource := &models.Source{ + BaseModel: models.BaseModel{ID: fmt.Sprintf("%025s", "1")}, DisplayName: "e621", Domain: "e621.net", } @@ -622,6 +625,7 @@ func TestGetUserSourceLinks(t *testing.T) { } faSource := &models.Source{ + BaseModel: models.BaseModel{ID: fmt.Sprintf("%025s", "2")}, DisplayName: "fa", Domain: "fa.net", } @@ -648,11 +652,11 @@ func TestGetUserSourceLinks(t *testing.T) { }, } - err = CreateUserWithRelationToSource(ctx, gormDB, "1", eSource.Domain, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) + err = CreateUserWithRelationToSource(ctx, gormDB, "1", models.AnthroveSourceID(eSource.ID), expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) if err != nil { t.Fatal(err) } - err = CreateUserWithRelationToSource(ctx, gormDB, "1", faSource.Domain, expectedResult["fa"].UserID, expectedResult["fa"].AccountUsername) + err = CreateUserWithRelationToSource(ctx, gormDB, "1", models.AnthroveSourceID(faSource.ID), expectedResult["fa"].UserID, expectedResult["fa"].AccountUsername) if err != nil { t.Fatal(err) } @@ -720,7 +724,7 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { if err != nil { t.Fatal(err) } - err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", post.ID) + err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", models.AnthrovePostID(post.ID)) if err != nil { t.Fatal(err) } @@ -733,7 +737,7 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { } for i, tag := range tags { - err = CreateTagAndReferenceToPost(ctx, gormDB, posts[i].ID, &tag) + err = CreateTagAndReferenceToPost(ctx, gormDB, models.AnthrovePostID(posts[i].ID), &tag) if err != nil { t.Fatal(err) } diff --git a/pkg/database/database.go b/pkg/database/database.go index f0c74f0..ee0a644 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -10,7 +10,7 @@ type OtterSpace interface { Connect(ctx context.Context, endpoint string, username string, password string, database string, port int, ssl string, timezone string) error // CreateUserWithRelationToSource adds a user with a relation to a source. - CreateUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error + CreateUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, accountId string, accountUsername string) error // CreateSource adds a new source to the database. CreateSource(ctx context.Context, anthroveSource *models.Source) error @@ -22,22 +22,22 @@ type OtterSpace interface { CreateTagAndReferenceToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error // CreateReferenceBetweenPostAndSource links a post with a source. - CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *models.PostReference) error + CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain) error // CreateReferenceBetweenUserAndPost links a user with a post. - CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUser *models.User, anthrovePost *models.Post) error + CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthrovePostID, anthrovePostID models.AnthrovePostID) error // CheckReferenceBetweenUserAndPost checks if a user-post link exists. - CheckReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) + CheckReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID models.AnthrovePostID) (bool, error) // GetPostByAnthroveID retrieves a post by its Anthrove ID. GetPostByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, error) - // GetPostBySourceURL retrieves a post by its source URL. - GetPostBySourceURL(ctx context.Context, sourceUrl string) (*models.Post, error) + // GetPostByURL retrieves a post by its source URL. + GetPostByURL(ctx context.Context, sourceUrl string) (*models.Post, error) // GetPostBySourceID retrieves a post by its source ID. - GetPostBySourceID(ctx context.Context, sourcePostID string) (*models.Post, error) + GetPostBySourceID(ctx context.Context, sourceID models.AnthroveSourceID) (*models.Post, error) // GetUserFavoritesCount retrieves the count of a user's favorites. GetUserFavoritesCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) @@ -46,7 +46,7 @@ type OtterSpace interface { GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) // GetUserSourceBySourceID retrieves a specified source link of a user. - GetUserSourceBySourceID(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID string) (map[string]models.UserSource, error) + GetUserSourceBySourceID(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID) (map[string]models.UserSource, error) // GetAllAnthroveUserIDs retrieves all Anthrove user IDs. GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) @@ -63,6 +63,6 @@ type OtterSpace interface { // GetAllSources retrieves all sources. GetAllSources(ctx context.Context) ([]models.Source, error) - // GetSourceByURL retrieves a source by its URL. - GetSourceByURL(ctx context.Context, sourceUrl string) (*models.Source, error) + // GetSourceByDomain retrieves a source by its URL. + GetSourceByDomain(ctx context.Context, sourceDomain models.AnthroveSourceDomain) (*models.Source, error) } diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 3503deb..0aa504d 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -64,8 +64,8 @@ func (p *postgresqlConnection) Connect(_ context.Context, endpoint string, usern return nil } -func (p *postgresqlConnection) CreateUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDomain string, userID string, username string) error { - return postgres.CreateUserWithRelationToSource(ctx, p.db, anthroveUserID, sourceDomain, userID, userID) +func (p *postgresqlConnection) CreateUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, accountId string, accountUsername string) error { + return postgres.CreateUserWithRelationToSource(ctx, p.db, anthroveUserID, sourceID, accountId, accountUsername) } func (p *postgresqlConnection) CreateSource(ctx context.Context, anthroveSource *models.Source) error { @@ -80,28 +80,28 @@ func (p *postgresqlConnection) CreateTagAndReferenceToPost(ctx context.Context, return postgres.CreateTagAndReferenceToPost(ctx, p.db, anthrovePostID, anthroveTag) } -func (p *postgresqlConnection) CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain string, anthrovePostRelationship *models.PostReference) error { - return postgres.CreateReferenceBetweenPostAndSource(ctx, p.db, anthrovePostID, sourceDomain, anthrovePostRelationship) +func (p *postgresqlConnection) CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain) error { + return postgres.CreateReferenceBetweenPostAndSource(ctx, p.db, anthrovePostID, sourceDomain) } -func (p *postgresqlConnection) CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUser *models.User, anthrovePost *models.Post) error { - return postgres.CreateReferenceBetweenUserAndPost(ctx, p.db, anthroveUser.ID, anthrovePost.ID) +func (p *postgresqlConnection) CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthrovePostID, anthrovePostID models.AnthrovePostID) error { + return postgres.CreateReferenceBetweenUserAndPost(ctx, p.db, anthroveUserID, anthrovePostID) } -func (p *postgresqlConnection) CheckReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID string, sourceUrl string) (bool, error) { - return postgres.CheckReferenceBetweenUserAndPost(ctx, p.db, anthroveUserID, models.AnthrovePostID(sourcePostID)) +func (p *postgresqlConnection) CheckReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) (bool, error) { + return postgres.CheckReferenceBetweenUserAndPost(ctx, p.db, anthroveUserID, anthrovePostID) } func (p *postgresqlConnection) GetPostByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, error) { return postgres.GetPostByAnthroveID(ctx, p.db, anthrovePost.ID) } -func (p *postgresqlConnection) GetPostBySourceURL(ctx context.Context, sourceUrl string) (*models.Post, error) { - return postgres.GetPostBySourceURL(ctx, p.db, sourceUrl) +func (p *postgresqlConnection) GetPostByURL(ctx context.Context, sourceUrl string) (*models.Post, error) { + return postgres.GetPostByURL(ctx, p.db, sourceUrl) } -func (p *postgresqlConnection) GetPostBySourceID(ctx context.Context, sourcePostID string) (*models.Post, error) { - return postgres.GetPostBySourceID(ctx, p.db, sourcePostID) +func (p *postgresqlConnection) GetPostBySourceID(ctx context.Context, sourceID models.AnthroveSourceID) (*models.Post, error) { + return postgres.GetPostBySourceID(ctx, p.db, sourceID) } func (p *postgresqlConnection) GetUserFavoritesCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) { @@ -112,8 +112,8 @@ func (p *postgresqlConnection) GetUserSourceLinks(ctx context.Context, anthroveU return postgres.GetUserSourceLinks(ctx, p.db, anthroveUserID) } -func (p *postgresqlConnection) GetUserSourceBySourceID(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceDisplayName string) (map[string]models.UserSource, error) { - return postgres.GetSpecifiedUserSourceLink(ctx, p.db, anthroveUserID, sourceDisplayName) +func (p *postgresqlConnection) GetUserSourceBySourceID(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID) (map[string]models.UserSource, error) { + return postgres.GetUserSourceBySourceID(ctx, p.db, anthroveUserID, sourceID) } func (p *postgresqlConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) { @@ -136,8 +136,8 @@ func (p *postgresqlConnection) GetAllSources(ctx context.Context) ([]models.Sour return postgres.GetAllSource(ctx, p.db) } -func (p *postgresqlConnection) GetSourceByURL(ctx context.Context, sourceUrl string) (*models.Source, error) { - return postgres.GetSourceByURL(ctx, p.db, sourceUrl) +func (p *postgresqlConnection) GetSourceByDomain(ctx context.Context, sourceDomain models.AnthroveSourceDomain) (*models.Source, error) { + return postgres.GetSourceByDomain(ctx, p.db, sourceDomain) } func (p *postgresqlConnection) migrateDatabase(connectionString string) error { diff --git a/pkg/models/const.go b/pkg/models/const.go index a9c3cf6..5b0e59a 100644 --- a/pkg/models/const.go +++ b/pkg/models/const.go @@ -2,6 +2,9 @@ package models type AnthroveUserID string type AnthrovePostID string +type AnthroveSourceID string +type AnthroveSourceDomain string + type Rating string type TagType string @@ -24,7 +27,6 @@ const ( ) func (r *Rating) Convert(e621Rating string) { - switch e621Rating { case "e": *r = NSFW @@ -35,5 +37,4 @@ func (r *Rating) Convert(e621Rating string) { default: *r = Unknown } - } diff --git a/pkg/models/orm.go b/pkg/models/orm.go index ff7bb64..7e74329 100644 --- a/pkg/models/orm.go +++ b/pkg/models/orm.go @@ -6,6 +6,12 @@ import ( "time" ) +type ID interface { + AnthroveUserID + AnthroveSourceID + AnthrovePostID +} + type BaseModel struct { ID string `gorm:"primaryKey"` CreatedAt time.Time -- 2.45.1 From a5f41e7a2d887b7f6944ab7a0778261c7ef6c689 Mon Sep 17 00:00:00 2001 From: soxx Date: Sun, 23 Jun 2024 22:39:54 +0200 Subject: [PATCH 069/124] fix(postgres): function mismatch with new types Signed-off-by: soxx --- pkg/database/database.go | 2 +- pkg/database/postgres.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/database/database.go b/pkg/database/database.go index ee0a644..cebec64 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -25,7 +25,7 @@ type OtterSpace interface { CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain) error // CreateReferenceBetweenUserAndPost links a user with a post. - CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthrovePostID, anthrovePostID models.AnthrovePostID) error + CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error // CheckReferenceBetweenUserAndPost checks if a user-post link exists. CheckReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID models.AnthrovePostID) (bool, error) diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 0aa504d..0aac161 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -84,7 +84,7 @@ func (p *postgresqlConnection) CreateReferenceBetweenPostAndSource(ctx context.C return postgres.CreateReferenceBetweenPostAndSource(ctx, p.db, anthrovePostID, sourceDomain) } -func (p *postgresqlConnection) CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthrovePostID, anthrovePostID models.AnthrovePostID) error { +func (p *postgresqlConnection) CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error { return postgres.CreateReferenceBetweenUserAndPost(ctx, p.db, anthroveUserID, anthrovePostID) } @@ -93,7 +93,7 @@ func (p *postgresqlConnection) CheckReferenceBetweenUserAndPost(ctx context.Cont } func (p *postgresqlConnection) GetPostByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, error) { - return postgres.GetPostByAnthroveID(ctx, p.db, anthrovePost.ID) + return postgres.GetPostByAnthroveID(ctx, p.db, models.AnthrovePostID(anthrovePost.ID)) } func (p *postgresqlConnection) GetPostByURL(ctx context.Context, sourceUrl string) (*models.Post, error) { -- 2.45.1 From 1ed6b912149ff619c6803fc8a437cc38fd8f79f0 Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 24 Jun 2024 11:58:29 +0200 Subject: [PATCH 070/124] ci(postgres): implemented CI for build check in sonarqube Signed-off-by: SoXX --- .gitea/workflows/ build_check.yaml | 39 ++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .gitea/workflows/ build_check.yaml diff --git a/.gitea/workflows/ build_check.yaml b/.gitea/workflows/ build_check.yaml new file mode 100644 index 0000000..db9f671 --- /dev/null +++ b/.gitea/workflows/ build_check.yaml @@ -0,0 +1,39 @@ +name: Gitea Build Check +run-name: ${{ gitea.actor }} is testing the build +on: + push: + branches: + - main + pull_request: + branches: [ "main" ] + +jobs: + Build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Setup Go environment + uses: https://github.com/actions/setup-go@v3 + with: + # The Go version to download (if necessary) and use. Supports semver spec and ranges. + go-version: 1.22.0 # optional + # Path to the go.mod file. + go-version-file: ./go.mod # optional + # Set this option to true if you want the action to always check for the latest available version that satisfies the version spec + check-latest: true # optional + # Used to specify whether caching is needed. Set to true, if you'd like to enable caching. + cache: true # optional + + - name: Execute Go Test files with coverage report + run: go test -v ./... -json -coverprofile="coverage.out" > "test-report.out" + + - uses: sonarsource/sonarqube-scan-action@master + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }} + with: + args: > + -Dsonar.projectKey=Anthrove---OtterSpace-SDK \ No newline at end of file -- 2.45.1 From bfa074fd9be4c2a259a16ca456c0a13796cc94a6 Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 24 Jun 2024 12:02:39 +0200 Subject: [PATCH 071/124] ci(postgres): fixed trigger Signed-off-by: SoXX --- .gitea/workflows/ build_check.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/ build_check.yaml b/.gitea/workflows/ build_check.yaml index db9f671..193bcfd 100644 --- a/.gitea/workflows/ build_check.yaml +++ b/.gitea/workflows/ build_check.yaml @@ -3,7 +3,7 @@ run-name: ${{ gitea.actor }} is testing the build on: push: branches: - - main + - develop/postgresql pull_request: branches: [ "main" ] -- 2.45.1 From b40d93c993cbd4caf1ed7239a147cc002396187e Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 24 Jun 2024 12:59:51 +0200 Subject: [PATCH 072/124] feat(postgres): config map Signed-off-by: SoXX --- pkg/database/database.go | 3 ++- pkg/database/postgres.go | 18 +++++++++++++----- pkg/models/config.go | 12 ++++++++++++ 3 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 pkg/models/config.go diff --git a/pkg/database/database.go b/pkg/database/database.go index cebec64..6db8e3c 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -2,12 +2,13 @@ package database import ( "context" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" ) type OtterSpace interface { // Connect establishes a connection to the database. - Connect(ctx context.Context, endpoint string, username string, password string, database string, port int, ssl string, timezone string) error + Connect(ctx context.Context, config models.DatabaseConfig) error // CreateUserWithRelationToSource adds a user with a relation to a source. CreateUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, accountId string, accountUsername string) error diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 0aac161..7c2371d 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -5,6 +5,10 @@ import ( "database/sql" "embed" "fmt" + log2 "log" + "os" + "time" + "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" _ "github.com/lib/pq" @@ -13,9 +17,6 @@ import ( gormPostgres "gorm.io/driver/postgres" "gorm.io/gorm" logger2 "gorm.io/gorm/logger" - log2 "log" - "os" - "time" ) //go:embed migrations/*.sql @@ -33,8 +34,15 @@ func NewPostgresqlConnection(debugOutput bool) OtterSpace { } } -func (p *postgresqlConnection) Connect(_ context.Context, endpoint string, username string, password string, database string, port int, ssl string, timezone string) error { - dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s TimeZone=%s", endpoint, username, password, database, port, ssl, timezone) +func (p *postgresqlConnection) Connect(_ context.Context, config models.DatabaseConfig) error { + var localSSL string + if config.SSL { + localSSL = "require" + } else { + localSSL = "disable" + } + + dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s TimeZone=%s", config.Endpoint, config.Username, config.Password, config.Database, config.Port, localSSL, config.Timezone) var err error err = p.migrateDatabase(dsn) diff --git a/pkg/models/config.go b/pkg/models/config.go new file mode 100644 index 0000000..2013b95 --- /dev/null +++ b/pkg/models/config.go @@ -0,0 +1,12 @@ +package models + +type DatabaseConfig struct { + Endpoint string `env:"DB_ENDPOINT,required"` + Username string `env:"DB_USERNAME,required"` + Password string `env:"DB_PASSWORD,required,unset"` + Database string `env:"DB_DATABASE,required"` + Port int `env:"DB_PORT,required" envDefault:"5432"` + SSL bool `env:"DB_SSL,required" envDefault:"true"` + Timezone string `env:"DB_TIMEZONE,required" envDefault:"Europe/Berlin"` + Debug bool `env:"DB_DEBUG" envDefault:"false"` +} -- 2.45.1 From 57729359d261e3b09239a6dd44e14e1777de6d56 Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 24 Jun 2024 13:13:32 +0200 Subject: [PATCH 073/124] feat(postgres): using only gorm Signed-off-by: SoXX --- pkg/database/postgres.go | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 7c2371d..7ce11d4 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -2,7 +2,6 @@ package database import ( "context" - "database/sql" "embed" "fmt" log2 "log" @@ -27,10 +26,9 @@ type postgresqlConnection struct { debug bool } -func NewPostgresqlConnection(debugOutput bool) OtterSpace { +func NewPostgresqlConnection() OtterSpace { return &postgresqlConnection{ - db: nil, - debug: debugOutput, + db: nil, } } @@ -45,13 +43,6 @@ func (p *postgresqlConnection) Connect(_ context.Context, config models.Database dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s TimeZone=%s", config.Endpoint, config.Username, config.Password, config.Database, config.Port, localSSL, config.Timezone) var err error - err = p.migrateDatabase(dsn) - if err != nil { - return err - } - - log.Infof("OtterSpace: migration compleate") - dbLogger := logger2.New(log2.New(os.Stdout, "\r\n", log2.LstdFlags), logger2.Config{ SlowThreshold: 200 * time.Millisecond, LogLevel: logger2.Warn, @@ -67,7 +58,14 @@ func (p *postgresqlConnection) Connect(_ context.Context, config models.Database return err } - log.Infof("OtterSpace: postgres connection established") + log.Infof("OtterSpace: database connection established") + + err = p.migrateDatabase(db) + if err != nil { + return err + } + + log.Infof("OtterSpace: migration compleate") return nil } @@ -148,11 +146,11 @@ func (p *postgresqlConnection) GetSourceByDomain(ctx context.Context, sourceDoma return postgres.GetSourceByDomain(ctx, p.db, sourceDomain) } -func (p *postgresqlConnection) migrateDatabase(connectionString string) error { +func (p *postgresqlConnection) migrateDatabase(dbPool *gorm.DB) error { dialect := "postgres" migrations := &migrate.EmbedFileSystemMigrationSource{FileSystem: embedMigrations, Root: "migrations"} - db, err := sql.Open(dialect, connectionString) + db, err := dbPool.DB() if err != nil { return fmt.Errorf("postgres migration: %v", err) } -- 2.45.1 From 30fa03ef9acad93082836b92c4b1b36782e6dc12 Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 24 Jun 2024 14:28:09 +0200 Subject: [PATCH 074/124] feat(postgres): added more tests Signed-off-by: SoXX --- internal/utils/slices_test.go | 60 +++++++++++++++++++++++++++++++++++ pkg/database/postgres.go | 2 ++ pkg/database/postgres_test.go | 26 +++++++++++++++ pkg/models/const_test.go | 59 ++++++++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+) create mode 100644 internal/utils/slices_test.go create mode 100644 pkg/database/postgres_test.go create mode 100644 pkg/models/const_test.go diff --git a/internal/utils/slices_test.go b/internal/utils/slices_test.go new file mode 100644 index 0000000..9f8cdc6 --- /dev/null +++ b/internal/utils/slices_test.go @@ -0,0 +1,60 @@ +package utils + +import ( + "reflect" + "testing" +) + +func TestGetOrDefault(t *testing.T) { + type args struct { + data map[string]any + key string + defaultVal any + } + tests := []struct { + name string + args args + want any + }{ + { + name: "Test 1: Nil map", + args: args{ + data: nil, + key: "key1", + defaultVal: "default", + }, + want: "default", + }, + { + name: "Test 2: Existing key", + args: args{ + data: map[string]interface{}{ + "key1": "value1", + "key2": "value2", + }, + key: "key1", + defaultVal: "default", + }, + want: "value1", + }, + { + name: "Test 3: Non-existing key", + args: args{ + data: map[string]interface{}{ + "key1": "value1", + "key2": "value2", + }, + key: "key3", + defaultVal: "default", + }, + want: "default", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := GetOrDefault(tt.args.data, tt.args.key, tt.args.defaultVal); !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetOrDefault() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 7ce11d4..44654aa 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -40,6 +40,8 @@ func (p *postgresqlConnection) Connect(_ context.Context, config models.Database localSSL = "disable" } + p.debug = config.Debug + dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s TimeZone=%s", config.Endpoint, config.Username, config.Password, config.Database, config.Port, localSSL, config.Timezone) var err error diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go new file mode 100644 index 0000000..0249f43 --- /dev/null +++ b/pkg/database/postgres_test.go @@ -0,0 +1,26 @@ +package database + +import ( + "testing" +) + +func TestNewPostgresqlConnection(t *testing.T) { + // Test + tests := []struct { + name string + want OtterSpace + }{ + { + name: "Test 1: Create new postgresql connection", + want: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.want != NewPostgresqlConnection() { + } else { + t.Errorf("NewPostgresqlConnection() = %s", tt.want) + } + }) + } +} diff --git a/pkg/models/const_test.go b/pkg/models/const_test.go new file mode 100644 index 0000000..cba0f75 --- /dev/null +++ b/pkg/models/const_test.go @@ -0,0 +1,59 @@ +package models + +import ( + "reflect" + "testing" +) + +func TestRating_Convert(t *testing.T) { + type args struct { + e621Rating string + } + tests := []struct { + name string + r *Rating + args args + want Rating + }{ + { + name: "Test 1: NSFW Rating", + r: new(Rating), + args: args{ + e621Rating: "e", + }, + want: NSFW, + }, + { + name: "Test 2: Questionable Rating", + r: new(Rating), + args: args{ + e621Rating: "q", + }, + want: Questionable, + }, + { + name: "Test 3: SFW Rating", + r: new(Rating), + args: args{ + e621Rating: "s", + }, + want: SFW, + }, + { + name: "Test 4: Unknown Rating", + r: new(Rating), + args: args{ + e621Rating: "x", + }, + want: Unknown, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.r.Convert(tt.args.e621Rating) + if !reflect.DeepEqual(*tt.r, tt.want) { + t.Errorf("Convert() = %v, want %v", *tt.r, tt.want) + } + }) + } +} -- 2.45.1 From 2a752adcacb389cfc4b86b47d943567c8a7f9e3f Mon Sep 17 00:00:00 2001 From: soxx Date: Mon, 24 Jun 2024 17:07:41 +0200 Subject: [PATCH 075/124] test(postgres): added more tests Signed-off-by: soxx --- internal/postgres/relationships.go | 4 +- internal/postgres/user.go | 8 +-- pkg/models/orm_test.go | 55 +++++++++++++++++ pkg/models/post.go | 2 +- pkg/models/postReference_test.go | 42 +++++++++++++ pkg/models/post_test.go | 38 ++++++++++++ pkg/models/source_test.go | 40 +++++++++++++ pkg/models/tag_test.go | 96 ++++++++++++++++++++++++++++++ pkg/models/user.go | 4 +- pkg/models/userFavorite.go | 4 +- pkg/models/userFavorite_test.go | 37 ++++++++++++ pkg/models/userSource_test.go | 42 +++++++++++++ pkg/models/user_test.go | 34 +++++++++++ 13 files changed, 395 insertions(+), 11 deletions(-) create mode 100644 pkg/models/orm_test.go create mode 100644 pkg/models/postReference_test.go create mode 100644 pkg/models/post_test.go create mode 100644 pkg/models/source_test.go create mode 100644 pkg/models/tag_test.go create mode 100644 pkg/models/userFavorite_test.go create mode 100644 pkg/models/userSource_test.go create mode 100644 pkg/models/user_test.go diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index 5c268f8..f719704 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -37,7 +37,7 @@ func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthr } func CreateReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error { - userFavorite := models.UserFavorite{ + userFavorite := models.UserFavorites{ UserID: string(anthroveUserID), PostID: string(anthrovePostID), } @@ -57,7 +57,7 @@ func CreateReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthrov func CheckReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) (bool, error) { var count int64 - err := db.WithContext(ctx).Model(&models.UserFavorite{}).Where("user_id = ? AND post_id = ?", string(anthroveUserID), string(anthrovePostID)).Count(&count).Error + err := db.WithContext(ctx).Model(&models.UserFavorites{}).Where("user_id = ? AND post_id = ?", string(anthroveUserID), string(anthrovePostID)).Count(&count).Error if err != nil { return false, err } diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 1b4e38f..9cdc2da 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -95,7 +95,7 @@ func GetUserFavoritesCount(ctx context.Context, db *gorm.DB, anthroveUserID mode } var count int64 - err := db.WithContext(ctx).Model(&models.UserFavorite{}).Where("user_id = ?", string(anthroveUserID)).Count(&count).Error + err := db.WithContext(ctx).Model(&models.UserFavorites{}).Where("user_id = ?", string(anthroveUserID)).Count(&count).Error if err != nil { log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, @@ -223,10 +223,10 @@ func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveU } func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) { - var userFavorites []models.UserFavorite + var userFavorites []models.UserFavorites var favoritePosts []models.Post - err := db.WithContext(ctx).Model(&models.UserFavorite{}).Where("user_id = ?", string(anthroveUserID)).Offset(skip).Limit(limit).Find(&userFavorites).Error + err := db.WithContext(ctx).Model(&models.UserFavorites{}).Where("user_id = ?", string(anthroveUserID)).Offset(skip).Limit(limit).Find(&userFavorites).Error if err != nil { log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, @@ -262,7 +262,7 @@ func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUse } func GetUserTagWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { - var userFavorites []models.UserFavorite + var userFavorites []models.UserFavorites err := db.WithContext(ctx).Where("user_id = ?", string(anthroveUserID)).Find(&userFavorites).Error if err != nil { log.WithFields(log.Fields{ diff --git a/pkg/models/orm_test.go b/pkg/models/orm_test.go new file mode 100644 index 0000000..d18fd2b --- /dev/null +++ b/pkg/models/orm_test.go @@ -0,0 +1,55 @@ +package models + +import ( + "gorm.io/gorm" + "testing" + "time" +) + +func TestBaseModel_BeforeCreate(t *testing.T) { + type fields struct { + ID string + CreatedAt time.Time + UpdatedAt time.Time + DeletedAt gorm.DeletedAt + } + type args struct { + db *gorm.DB + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + { + name: "Test 1: Prefilled ID", + fields: fields{ + ID: "1", + }, + args: args{db: nil}, + wantErr: false, + }, + { + name: "Test 1: Autogenerate ID", + fields: fields{ + ID: "", + }, + args: args{db: nil}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + base := &BaseModel{ + ID: tt.fields.ID, + CreatedAt: tt.fields.CreatedAt, + UpdatedAt: tt.fields.UpdatedAt, + DeletedAt: tt.fields.DeletedAt, + } + if err := base.BeforeCreate(tt.args.db); (err != nil) != tt.wantErr { + t.Errorf("BeforeCreate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/models/post.go b/pkg/models/post.go index bac8a50..9aef5e7 100644 --- a/pkg/models/post.go +++ b/pkg/models/post.go @@ -5,7 +5,7 @@ type Post struct { BaseModel Rating Rating `gorm:"type:enum('safe','questionable','explicit')"` Tags []Tag `gorm:"many2many:post_tags;"` - Favorites []UserFavorite `gorm:"foreignKey:PostID"` + Favorites []UserFavorites `gorm:"foreignKey:PostID"` References []PostReference `gorm:"foreignKey:PostID"` } diff --git a/pkg/models/postReference_test.go b/pkg/models/postReference_test.go new file mode 100644 index 0000000..232a695 --- /dev/null +++ b/pkg/models/postReference_test.go @@ -0,0 +1,42 @@ +package models + +import "testing" + +func TestPostReference_TableName(t *testing.T) { + type fields struct { + PostID string + SourceID string + URL string + SourcePostID string + FullFileURL string + PreviewFileURL string + SampleFileURL string + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "Test 1: PostReference", + fields: fields{}, + want: "PostReference", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + po := PostReference{ + PostID: tt.fields.PostID, + SourceID: tt.fields.SourceID, + URL: tt.fields.URL, + SourcePostID: tt.fields.SourcePostID, + FullFileURL: tt.fields.FullFileURL, + PreviewFileURL: tt.fields.PreviewFileURL, + SampleFileURL: tt.fields.SampleFileURL, + } + if got := po.TableName(); got != tt.want { + t.Errorf("TableName() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/models/post_test.go b/pkg/models/post_test.go new file mode 100644 index 0000000..c90852e --- /dev/null +++ b/pkg/models/post_test.go @@ -0,0 +1,38 @@ +package models + +import "testing" + +func TestPost_TableName(t *testing.T) { + type fields struct { + BaseModel BaseModel + Rating Rating + Tags []Tag + Favorites []UserFavorites + References []PostReference + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "Test 1: Is name Post", + fields: fields{}, + want: "Post", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + po := Post{ + BaseModel: tt.fields.BaseModel, + Rating: tt.fields.Rating, + Tags: tt.fields.Tags, + Favorites: tt.fields.Favorites, + References: tt.fields.References, + } + if got := po.TableName(); got != tt.want { + t.Errorf("TableName() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/models/source_test.go b/pkg/models/source_test.go new file mode 100644 index 0000000..1a5ff8c --- /dev/null +++ b/pkg/models/source_test.go @@ -0,0 +1,40 @@ +package models + +import "testing" + +func TestSource_TableName(t *testing.T) { + type fields struct { + BaseModel BaseModel + DisplayName string + Domain string + Icon string + UserSources []UserSource + References []PostReference + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "Test 1: Is name Source", + fields: fields{}, + want: "Source", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + so := Source{ + BaseModel: tt.fields.BaseModel, + DisplayName: tt.fields.DisplayName, + Domain: tt.fields.Domain, + Icon: tt.fields.Icon, + UserSources: tt.fields.UserSources, + References: tt.fields.References, + } + if got := so.TableName(); got != tt.want { + t.Errorf("TableName() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/models/tag_test.go b/pkg/models/tag_test.go new file mode 100644 index 0000000..6f66b18 --- /dev/null +++ b/pkg/models/tag_test.go @@ -0,0 +1,96 @@ +package models + +import "testing" + +func TestTagAlias_TableName(t *testing.T) { + type fields struct { + Name string + TagID string + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "Test 1: Is Name TagAlias", + fields: fields{}, + want: "TagAlias", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ta := TagAlias{ + Name: tt.fields.Name, + TagID: tt.fields.TagID, + } + if got := ta.TableName(); got != tt.want { + t.Errorf("TableName() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestTagGroup_TableName(t *testing.T) { + type fields struct { + Name string + TagID string + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "Test 1: Is name TagGroup", + fields: fields{}, + want: "TagGroup", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ta := TagGroup{ + Name: tt.fields.Name, + TagID: tt.fields.TagID, + } + if got := ta.TableName(); got != tt.want { + t.Errorf("TableName() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestTag_TableName(t *testing.T) { + type fields struct { + Name string + Type TagType + Aliases []TagAlias + Groups []TagGroup + Posts []Post + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "Test 1: Is name Tag", + fields: fields{}, + want: "Tag", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ta := Tag{ + Name: tt.fields.Name, + Type: tt.fields.Type, + Aliases: tt.fields.Aliases, + Groups: tt.fields.Groups, + Posts: tt.fields.Posts, + } + if got := ta.TableName(); got != tt.want { + t.Errorf("TableName() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/models/user.go b/pkg/models/user.go index 96dd70e..7f723e6 100644 --- a/pkg/models/user.go +++ b/pkg/models/user.go @@ -3,8 +3,8 @@ package models // User model type User struct { BaseModel - Favorites []UserFavorite `gorm:"foreignKey:UserID"` - Sources []UserSource `gorm:"foreignKey:UserID"` + Favorites []UserFavorites `gorm:"foreignKey:UserID"` + Sources []UserSource `gorm:"foreignKey:UserID"` } func (User) TableName() string { diff --git a/pkg/models/userFavorite.go b/pkg/models/userFavorite.go index 8ccd106..3bebe91 100644 --- a/pkg/models/userFavorite.go +++ b/pkg/models/userFavorite.go @@ -2,13 +2,13 @@ package models import "time" -type UserFavorite struct { +type UserFavorites struct { UserID string `gorm:"primaryKey"` PostID string `gorm:"primaryKey"` CreatedAt time.Time } -func (UserFavorite) TableName() string { +func (UserFavorites) TableName() string { return "UserFavorites" } diff --git a/pkg/models/userFavorite_test.go b/pkg/models/userFavorite_test.go new file mode 100644 index 0000000..3b69143 --- /dev/null +++ b/pkg/models/userFavorite_test.go @@ -0,0 +1,37 @@ +package models + +import ( + "testing" + "time" +) + +func TestUserFavorite_TableName(t *testing.T) { + type fields struct { + UserID string + PostID string + CreatedAt time.Time + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "Test 1: Is name UserFavorites", + fields: fields{}, + want: "UserFavorites", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + us := UserFavorites{ + UserID: tt.fields.UserID, + PostID: tt.fields.PostID, + CreatedAt: tt.fields.CreatedAt, + } + if got := us.TableName(); got != tt.want { + t.Errorf("TableName() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/models/userSource_test.go b/pkg/models/userSource_test.go new file mode 100644 index 0000000..ff8cd95 --- /dev/null +++ b/pkg/models/userSource_test.go @@ -0,0 +1,42 @@ +package models + +import "testing" + +func TestUserSource_TableName(t *testing.T) { + type fields struct { + User User + UserID string + Source Source + SourceID string + ScrapeTimeInterval string + AccountUsername string + AccountID string + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "Test 1: Is name UserSource", + fields: fields{}, + want: "UserSource", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + us := UserSource{ + User: tt.fields.User, + UserID: tt.fields.UserID, + Source: tt.fields.Source, + SourceID: tt.fields.SourceID, + ScrapeTimeInterval: tt.fields.ScrapeTimeInterval, + AccountUsername: tt.fields.AccountUsername, + AccountID: tt.fields.AccountID, + } + if got := us.TableName(); got != tt.want { + t.Errorf("TableName() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/models/user_test.go b/pkg/models/user_test.go new file mode 100644 index 0000000..fa2c511 --- /dev/null +++ b/pkg/models/user_test.go @@ -0,0 +1,34 @@ +package models + +import "testing" + +func TestUser_TableName(t *testing.T) { + type fields struct { + BaseModel BaseModel + Favorites []UserFavorites + Sources []UserSource + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "Test 1: Is name User", + fields: fields{}, + want: "User", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + us := User{ + BaseModel: tt.fields.BaseModel, + Favorites: tt.fields.Favorites, + Sources: tt.fields.Sources, + } + if got := us.TableName(); got != tt.want { + t.Errorf("TableName() = %v, want %v", got, tt.want) + } + }) + } +} -- 2.45.1 From 97758b180ebbc6fb8e16542d616b790400d25e3c Mon Sep 17 00:00:00 2001 From: soxx Date: Mon, 24 Jun 2024 22:07:34 +0200 Subject: [PATCH 076/124] test(postgres): added more tests and some fixes Signed-off-by: soxx --- internal/postgres/post_test.go | 4 +- pkg/database/database.go | 2 +- pkg/database/postgres.go | 4 +- pkg/database/postgres_test.go | 766 +++++++++++++++++++++++++++++++++ test/helper.go | 42 ++ 5 files changed, 814 insertions(+), 4 deletions(-) diff --git a/internal/postgres/post_test.go b/internal/postgres/post_test.go index cf2ebc4..70d2b37 100644 --- a/internal/postgres/post_test.go +++ b/internal/postgres/post_test.go @@ -348,8 +348,10 @@ func TestGetPostBySourceID(t *testing.T) { func checkPost(got *models.Post, want *models.Post) bool { - if got == nil { + if got == nil && want == nil { return true + } else if got == nil || want == nil { + return false } if got.ID != want.ID { diff --git a/pkg/database/database.go b/pkg/database/database.go index 6db8e3c..10d203a 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -32,7 +32,7 @@ type OtterSpace interface { CheckReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID models.AnthrovePostID) (bool, error) // GetPostByAnthroveID retrieves a post by its Anthrove ID. - GetPostByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, error) + GetPostByAnthroveID(ctx context.Context, anthrovePostID models.AnthrovePostID) (*models.Post, error) // GetPostByURL retrieves a post by its source URL. GetPostByURL(ctx context.Context, sourceUrl string) (*models.Post, error) diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 44654aa..4245c9b 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -100,8 +100,8 @@ func (p *postgresqlConnection) CheckReferenceBetweenUserAndPost(ctx context.Cont return postgres.CheckReferenceBetweenUserAndPost(ctx, p.db, anthroveUserID, anthrovePostID) } -func (p *postgresqlConnection) GetPostByAnthroveID(ctx context.Context, anthrovePost *models.Post) (*models.Post, error) { - return postgres.GetPostByAnthroveID(ctx, p.db, models.AnthrovePostID(anthrovePost.ID)) +func (p *postgresqlConnection) GetPostByAnthroveID(ctx context.Context, anthrovePostID models.AnthrovePostID) (*models.Post, error) { + return postgres.GetPostByAnthroveID(ctx, p.db, anthrovePostID) } func (p *postgresqlConnection) GetPostByURL(ctx context.Context, sourceUrl string) (*models.Post, error) { diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index 0249f43..d14a354 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -1,6 +1,11 @@ package database import ( + "context" + "fmt" + "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/test" "testing" ) @@ -24,3 +29,764 @@ func TestNewPostgresqlConnection(t *testing.T) { }) } } + +func Test_postgresqlConnection_Connect(t *testing.T) { + + // Setup trow away container + ctx := context.Background() + container, _, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Tests + + dbConfig, err := test.DatabaseModesFromConnectionString(ctx, container) + if err != nil { + t.Fatalf("Could not parse database config: %v", err) + } + + // Test + type args struct { + in0 context.Context + config models.DatabaseConfig + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Connect to postgresql connection", + args: args{ + in0: ctx, + config: *dbConfig, + }, + wantErr: false, + }, + { + name: "Test 1: Empty connection config", + args: args{ + in0: ctx, + config: models.DatabaseConfig{}, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{} + if err := p.Connect(tt.args.in0, tt.args.config); (err != nil) != tt.wantErr { + t.Errorf("Connect() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_postgresqlConnection_CreateUserWithRelationToSource(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + source := &models.Source{ + BaseModel: models.BaseModel{ID: fmt.Sprintf("%025s", "1")}, + DisplayName: "e621", + Domain: "e621.net", + Icon: "icon.e621.net", + } + err = postgres.CreateSource(ctx, gormDB, source) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + anthroveUserID models.AnthroveUserID + sourceID models.AnthroveSourceID + accountId string + accountUsername string + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid anthroveUserID, sourceID, accountId, accountUsername", + args: args{ + ctx: ctx, + anthroveUserID: "1", + sourceID: models.AnthroveSourceID(source.ID), + accountId: "e1", + accountUsername: "marius", + }, + wantErr: false, + }, + { + name: "Test 2: Invalid anthroveUserID, valid sourceID, accountId, accountUsername", + args: args{ + ctx: ctx, + anthroveUserID: "2", + sourceID: models.AnthroveSourceID(source.ID), + accountId: "e1", + accountUsername: "marius", + }, + wantErr: true, + }, + { + name: "Test 3: Empty anthroveUserID", + args: args{ + ctx: ctx, + anthroveUserID: "", + sourceID: models.AnthroveSourceID(source.ID), + accountId: "e1", + accountUsername: "marius", + }, + wantErr: true, + }, + { + name: "Test 4: invalid sourceID", + args: args{ + ctx: ctx, + anthroveUserID: "1", + sourceID: "fa.net", + accountId: "e1", + accountUsername: "marius", + }, + wantErr: true, + }, + { + name: "Test 5: no accountId", + args: args{ + ctx: ctx, + anthroveUserID: "1", + sourceID: models.AnthroveSourceID(source.ID), + accountId: "", + accountUsername: "marius", + }, + wantErr: true, + }, + { + name: "Test 6: no accountUsername", + args: args{ + ctx: ctx, + anthroveUserID: "1", + sourceID: models.AnthroveSourceID(source.ID), + accountId: "aa", + accountUsername: "", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.CreateUserWithRelationToSource(tt.args.ctx, tt.args.anthroveUserID, tt.args.sourceID, tt.args.accountId, tt.args.accountUsername); (err != nil) != tt.wantErr { + t.Errorf("CreateUserWithRelationToSource() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_postgresqlConnection_CreateSource(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validSource := &models.Source{ + DisplayName: "e621", + Domain: "e621.net", + Icon: "icon.e621.net", + } + + invalidSource := &models.Source{ + Domain: "", + } + + // Test + type args struct { + ctx context.Context + anthroveSource *models.Source + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid anthroveSource", + args: args{ + ctx: ctx, + anthroveSource: validSource, + }, + wantErr: false, + }, + { + name: "Test 2: inValid anthroveSource", + args: args{ + ctx: ctx, + anthroveSource: invalidSource, + }, + wantErr: true, + }, + { + name: "Test 3: unique anthroveSource", + args: args{ + ctx: ctx, + anthroveSource: validSource, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.CreateSource(tt.args.ctx, tt.args.anthroveSource); (err != nil) != tt.wantErr { + t.Errorf("CreateSource() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_postgresqlConnection_CreatePost(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Tests + + validPost := &models.Post{ + BaseModel: models.BaseModel{ + ID: fmt.Sprintf("%025s", "1"), + }, + Rating: "safe", + } + + invalidPost := &models.Post{ + Rating: "error", + } + + // Test + type args struct { + ctx context.Context + anthrovePost *models.Post + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid AnthrovePostID and Rating", + args: args{ + ctx: context.Background(), + anthrovePost: validPost, + }, + wantErr: false, + }, + { + name: "Test 2: Invalid Rating", + args: args{ + ctx: context.Background(), + anthrovePost: invalidPost, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.CreatePost(tt.args.ctx, tt.args.anthrovePost); (err != nil) != tt.wantErr { + t.Errorf("CreatePost() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_postgresqlConnection_CreateTagAndReferenceToPost(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + post := &models.Post{ + BaseModel: models.BaseModel{ + ID: fmt.Sprintf("%025s", "1"), + }, + Rating: "safe", + } + + err = postgres.CreatePost(ctx, gormDB, post) + if err != nil { + t.Fatal(err) + } + + tag := &models.Tag{ + Name: "JayTheFerret", + Type: "artist", + } + + // Test + type args struct { + ctx context.Context + anthrovePostID models.AnthrovePostID + anthroveTag *models.Tag + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid PostID and Tag", + args: args{ + ctx: ctx, + anthrovePostID: models.AnthrovePostID(post.ID), + anthroveTag: tag, + }, + wantErr: false, + }, + { + name: "Test 2: Valid PostID and no Tag", + args: args{ + ctx: ctx, + anthrovePostID: models.AnthrovePostID(post.ID), + anthroveTag: nil, + }, + wantErr: true, + }, + { + name: "Test 3: Invalid PostID and valid Tag", + args: args{ + ctx: ctx, + anthrovePostID: "123456", + anthroveTag: tag, + }, + wantErr: true, + }, + { + name: "Test 4: No PostID and valid Tag", + args: args{ + ctx: ctx, + anthrovePostID: "", + anthroveTag: tag, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.CreateTagAndReferenceToPost(tt.args.ctx, tt.args.anthrovePostID, tt.args.anthroveTag); (err != nil) != tt.wantErr { + t.Errorf("CreateTagAndReferenceToPost() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_postgresqlConnection_CreateReferenceBetweenPostAndSource(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + post := &models.Post{ + BaseModel: models.BaseModel{ + ID: fmt.Sprintf("%025s", "1"), + }, + Rating: "safe", + } + + err = postgres.CreatePost(ctx, gormDB, post) + if err != nil { + t.Fatal(err) + } + + source := &models.Source{ + DisplayName: "e621", + Domain: "e621.net", + Icon: "icon.e621.net", + } + err = postgres.CreateSource(ctx, gormDB, source) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + anthrovePostID models.AnthrovePostID + sourceDomain models.AnthroveSourceDomain + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid AnthrovePostID and anthroveSourceDomain", + args: args{ + ctx: ctx, + anthrovePostID: models.AnthrovePostID(post.ID), + sourceDomain: "e621.net", + }, + wantErr: false, + }, + { + name: "Test 2: Invalid AnthrovePostID and Valid anthroveSourceDomain", + args: args{ + ctx: ctx, + anthrovePostID: "123456", + sourceDomain: "e621.net", + }, + wantErr: true, + }, + { + name: "Test 3: Invalid anthroveSourceDomain and Valid AnthrovePostID", + args: args{ + ctx: ctx, + anthrovePostID: "1234", + sourceDomain: "fa.banana", + }, + wantErr: true, + }, + { + name: "Test 4: Invalid anthroveSourceDomain and Invalid AnthrovePostID", + args: args{ + ctx: ctx, + anthrovePostID: "696969", + sourceDomain: "hehe.funny.number", + }, + wantErr: true, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.CreateReferenceBetweenPostAndSource(tt.args.ctx, tt.args.anthrovePostID, tt.args.sourceDomain); (err != nil) != tt.wantErr { + t.Errorf("CreateReferenceBetweenPostAndSource() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_postgresqlConnection_CreateReferenceBetweenUserAndPost(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + err = postgres.CreateUser(ctx, gormDB, "1") + if err != nil { + t.Fatal(err) + } + + post := &models.Post{ + BaseModel: models.BaseModel{ + ID: fmt.Sprintf("%025s", "1"), + }, + Rating: "safe", + } + + err = postgres.CreatePost(ctx, gormDB, post) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + anthroveUserID models.AnthroveUserID + anthrovePostID models.AnthrovePostID + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid AnthroveUserID and AnthrovePostID", + args: args{ + ctx: ctx, + anthroveUserID: "1", + anthrovePostID: models.AnthrovePostID(post.ID), + }, + wantErr: false, + }, + { + name: "Test 2: Valid AnthroveUserID and invalid AnthrovePostID", + args: args{ + ctx: ctx, + anthroveUserID: "1", + anthrovePostID: "123456", + }, + wantErr: true, + }, + { + name: "Test 3: Valid AnthrovePostID and invalid AnthroveUserID", + args: args{ + ctx: ctx, + anthroveUserID: "123", + anthrovePostID: "1234", + }, + wantErr: true, + }, + { + name: "Test 4: Invalid AnthrovePostID and invalid AnthroveUserID", + args: args{ + ctx: ctx, + anthroveUserID: "123", + anthrovePostID: "123456", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.CreateReferenceBetweenUserAndPost(tt.args.ctx, tt.args.anthroveUserID, tt.args.anthrovePostID); (err != nil) != tt.wantErr { + t.Errorf("CreateReferenceBetweenUserAndPost() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_postgresqlConnection_CheckReferenceBetweenUserAndPost(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + err = postgres.CreateUser(ctx, gormDB, "1") + if err != nil { + t.Fatal(err) + } + + post := &models.Post{ + BaseModel: models.BaseModel{ + ID: fmt.Sprintf("%025s", "1"), + }, + Rating: "safe", + } + + err = postgres.CreatePost(ctx, gormDB, post) + if err != nil { + t.Fatal(err) + } + + err = postgres.CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", models.AnthrovePostID(post.ID)) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + anthroveUserID models.AnthroveUserID + anthrovePostID models.AnthrovePostID + } + tests := []struct { + name string + args args + want bool + wantErr bool + }{ + { + name: "Test 1: Valid AnthroveUserID and AnthrovePostID", + args: args{ + ctx: ctx, + anthroveUserID: "1", + anthrovePostID: models.AnthrovePostID(post.ID), + }, + want: true, + wantErr: false, + }, + { + name: "Test 2: Valid AnthroveUserID and invalid AnthrovePostID", + args: args{ + ctx: ctx, + anthroveUserID: "1", + anthrovePostID: "qadw", + }, + want: false, + wantErr: false, + }, + { + name: "Test 3: Valid AnthrovePostID and invalid AnthroveUserID", + args: args{ + ctx: ctx, + anthroveUserID: "123", + anthrovePostID: models.AnthrovePostID(post.ID), + }, + want: false, + wantErr: false, + }, + { + name: "Test 4: Invalid AnthrovePostID and invalid AnthroveUserID", + args: args{ + ctx: ctx, + anthroveUserID: "123", + anthrovePostID: "123456", + }, + want: false, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.CheckReferenceBetweenUserAndPost(tt.args.ctx, tt.args.anthroveUserID, tt.args.anthrovePostID) + if (err != nil) != tt.wantErr { + t.Errorf("CheckReferenceBetweenUserAndPost() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("CheckReferenceBetweenUserAndPost() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_postgresqlConnection_GetPostByAnthroveID(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Tests + + post := &models.Post{ + BaseModel: models.BaseModel{ + ID: fmt.Sprintf("%025s", "1"), + }, + Rating: "safe", + } + + err = postgres.CreatePost(ctx, gormDB, post) + if err != nil { + t.Fatal("Could not create post", err) + } + + // Test + type args struct { + ctx context.Context + anthrovePost models.AnthrovePostID + } + tests := []struct { + name string + args args + want *models.Post + wantErr bool + }{ + { + name: "Test 1: Valid anthrovePostID", + args: args{ + ctx: ctx, + anthrovePost: models.AnthrovePostID(post.ID), + }, + want: post, + wantErr: false, + }, + { + name: "Test 2: No anthrovePostID", + args: args{ + ctx: ctx, + anthrovePost: "nil", + }, + want: nil, + wantErr: true, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetPostByAnthroveID(tt.args.ctx, tt.args.anthrovePost) + if (err != nil) != tt.wantErr { + t.Errorf("GetPostByAnthroveID() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !checkPost(got, tt.want) { + t.Errorf("GetPostByAnthroveID() got = %v, want %v", got, tt.want) + } + }) + } +} + +func checkPost(got *models.Post, want *models.Post) bool { + + if got == nil && want == nil { + return true + } else if got == nil || want == nil { + return false + } + + if got.ID != want.ID { + return false + } + + if got.Rating != want.Rating { + return false + } + + return true +} diff --git a/test/helper.go b/test/helper.go index 501ac62..6fed12e 100644 --- a/test/helper.go +++ b/test/helper.go @@ -3,11 +3,15 @@ package test import ( "context" "database/sql" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" migrate "github.com/rubenv/sql-migrate" postgrescontainer "github.com/testcontainers/testcontainers-go/modules/postgres" "gorm.io/driver/postgres" "gorm.io/gorm" "gorm.io/gorm/logger" + "net/url" + "strconv" + "strings" "time" "github.com/testcontainers/testcontainers-go" @@ -78,3 +82,41 @@ func getGormDB(connectionString string) (*gorm.DB, error) { Logger: logger.Default.LogMode(logger.Info), }) } + +func DatabaseModesFromConnectionString(ctx context.Context, pgContainer *postgrescontainer.PostgresContainer) (*models.DatabaseConfig, error) { + var err error + + connectionString, err := pgContainer.ConnectionString(ctx) + if err != nil { + return nil, err + } + + url, err := url.Parse(connectionString) + if err != nil { + return nil, err + } + + split := strings.Split(url.Host, ":") + host := split[0] + + port, err := strconv.Atoi(split[1]) + if err != nil { + return nil, err + } + + database := strings.TrimPrefix(url.Path, "/") + + username := url.User.Username() + password, _ := url.User.Password() + + return &models.DatabaseConfig{ + Endpoint: host, + Username: username, + Password: password, + Database: database, + Port: port, + SSL: false, + Timezone: "Europe/Berlin", + Debug: true, + }, nil +} -- 2.45.1 From 8ea3369744c1f9e61ec88d9b90e4ffd9be1e05bd Mon Sep 17 00:00:00 2001 From: soxx Date: Mon, 24 Jun 2024 22:18:34 +0200 Subject: [PATCH 077/124] docs(postgres): added all the sonarqube badges Signed-off-by: soxx --- README.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ffd7f3f..af7e618 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,18 @@ # OtterSpace SDK +[![Bugs](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=bugs&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) +[![Code Smells](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=code_smells&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) +[![Coverage](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=coverage&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) +[![Duplicated Lines (%)](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=duplicated_lines_density&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) +[![Lines of Code](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=ncloc&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) +[![Maintainability Rating](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=sqale_rating&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) +[![Quality Gate Status](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=alert_status&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) +[![Reliability Rating](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=reliability_rating&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) +[![Security Hotspots](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=security_hotspots&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) +[![Security Rating](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=security_rating&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) +[![Technical Debt](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=sqale_index&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) +[![Vulnerabilities](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=vulnerabilities&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) + The OtterSpace SDK is a Go package for interacting with the OtterSpace API. It provides methods for connecting to the API, adding and linking users, posts, and sources, and retrieving information about users and posts. ## Installation @@ -19,28 +32,21 @@ package main import ( "context" "fmt" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/pkg/database" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" ) func main() { var err error dbDebug := false ctx := context.Background() - + pgClient := database.NewPostgresqlConnection(dbDebug) err = pgClient.Connect(ctx, "your-endpoint", "your-username", "your-password", "anthrove", 5432, "disable", "Europe/Berlin") if err != nil { fmt.Println(err) return } - - graphClient := database.NewGraphConnection(dbDebug) - err = graphClient.Connect(ctx, "your-endpoint", "your-username", "your-password", "NOT USED",0,"NOT USED","NOT USED") - if err != nil { - fmt.Println(err) - return - } // further usage of the client... } ``` -- 2.45.1 From df14171badd2a442069b9ec0bbffc7a45b2bee40 Mon Sep 17 00:00:00 2001 From: soxx Date: Mon, 24 Jun 2024 22:29:01 +0200 Subject: [PATCH 078/124] docs(postgres): added all the sonarqube badges Signed-off-by: soxx --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index af7e618..fd6a43f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # OtterSpace SDK +#### ALL THE BADGES GIT + +![Build Check Runner](https://git.dragse.it/anthrove/otter-space-sdk/actions/workflows/build_check.yaml/badge.svg) + +#### ALL THE BADGES SONARQUBE [![Bugs](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=bugs&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) [![Code Smells](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=code_smells&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) [![Coverage](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=coverage&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) @@ -10,7 +15,6 @@ [![Reliability Rating](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=reliability_rating&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) [![Security Hotspots](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=security_hotspots&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) [![Security Rating](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=security_rating&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) -[![Technical Debt](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=sqale_index&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) [![Vulnerabilities](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=vulnerabilities&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) The OtterSpace SDK is a Go package for interacting with the OtterSpace API. It provides methods for connecting to the API, adding and linking users, posts, and sources, and retrieving information about users and posts. -- 2.45.1 From 895c4cd436c3a77178d33f901edc3e90eaf62439 Mon Sep 17 00:00:00 2001 From: soxx Date: Mon, 24 Jun 2024 22:30:05 +0200 Subject: [PATCH 079/124] docs(postgres): rearranged Signed-off-by: soxx --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fd6a43f..a01f593 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ -# OtterSpace SDK - -#### ALL THE BADGES GIT +#### ALL THE BADGES: GIT ![Build Check Runner](https://git.dragse.it/anthrove/otter-space-sdk/actions/workflows/build_check.yaml/badge.svg) -#### ALL THE BADGES SONARQUBE +#### ALL THE BADGES: SONARQUBE + [![Bugs](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=bugs&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) [![Code Smells](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=code_smells&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) [![Coverage](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=coverage&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) @@ -17,6 +16,8 @@ [![Security Rating](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=security_rating&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) [![Vulnerabilities](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=vulnerabilities&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) +# OtterSpace SDK + The OtterSpace SDK is a Go package for interacting with the OtterSpace API. It provides methods for connecting to the API, adding and linking users, posts, and sources, and retrieving information about users and posts. ## Installation -- 2.45.1 From d90736b1b6154177db1f9291541543387d2fc518 Mon Sep 17 00:00:00 2001 From: soxx Date: Mon, 24 Jun 2024 22:30:57 +0200 Subject: [PATCH 080/124] docs(postgres): rearranged Signed-off-by: soxx --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a01f593..57ec96e 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,14 @@ -#### ALL THE BADGES: GIT ![Build Check Runner](https://git.dragse.it/anthrove/otter-space-sdk/actions/workflows/build_check.yaml/badge.svg) - -#### ALL THE BADGES: SONARQUBE - [![Bugs](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=bugs&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) [![Code Smells](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=code_smells&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) [![Coverage](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=coverage&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) + [![Duplicated Lines (%)](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=duplicated_lines_density&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) [![Lines of Code](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=ncloc&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) [![Maintainability Rating](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=sqale_rating&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) [![Quality Gate Status](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=alert_status&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) + [![Reliability Rating](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=reliability_rating&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) [![Security Hotspots](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=security_hotspots&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) [![Security Rating](https://sonarqube.dragse.de/api/project_badges/measure?project=Anthrove---OtterSpace-SDK&metric=security_rating&token=sqb_96012ffdd64ce721d7f9c82bfa77aa27a5c1fd38)](https://sonarqube.dragse.de/dashboard?id=Anthrove---OtterSpace-SDK) -- 2.45.1 From 31c424912910ae9d670041fbc03415da76a0706d Mon Sep 17 00:00:00 2001 From: soxx Date: Mon, 24 Jun 2024 22:31:18 +0200 Subject: [PATCH 081/124] refactor(postgres): use generics for IDs Signed-off-by: soxx --- pkg/models/orm.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/pkg/models/orm.go b/pkg/models/orm.go index 7e74329..7235e57 100644 --- a/pkg/models/orm.go +++ b/pkg/models/orm.go @@ -7,27 +7,26 @@ import ( ) type ID interface { - AnthroveUserID - AnthroveSourceID - AnthrovePostID + AnthroveUserID | AnthroveSourceID | AnthrovePostID } -type BaseModel struct { - ID string `gorm:"primaryKey"` +type BaseModel[T ID] struct { + ID T `gorm:"primaryKey"` CreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAt `gorm:"index"` } -func (base *BaseModel) BeforeCreate(db *gorm.DB) error { +func (base *BaseModel[T]) BeforeCreate(db *gorm.DB) error { + var defaultVar T - if base.ID == "" { + if base.ID == defaultVar { id, err := gonanoid.New(25) if err != nil { return err } - base.ID = id + base.ID = T(id) } return nil -- 2.45.1 From 5aac1f2916ad99c1ca48e97019a949ae4311d633 Mon Sep 17 00:00:00 2001 From: soxx Date: Tue, 25 Jun 2024 09:09:18 +0200 Subject: [PATCH 082/124] feat(postgres): start implementing new generic orm model Signed-off-by: soxx --- internal/postgres/post_test.go | 30 +++++++----- internal/postgres/relationships.go | 2 +- internal/postgres/relationships_test.go | 20 ++++---- internal/postgres/tag.go | 4 +- internal/postgres/tag_test.go | 4 +- internal/postgres/user.go | 12 ++--- internal/postgres/user_test.go | 64 +++++++++++++------------ pkg/models/post.go | 2 +- pkg/models/source.go | 2 +- pkg/models/user.go | 2 +- 10 files changed, 75 insertions(+), 67 deletions(-) diff --git a/internal/postgres/post_test.go b/internal/postgres/post_test.go index 70d2b37..389e339 100644 --- a/internal/postgres/post_test.go +++ b/internal/postgres/post_test.go @@ -23,8 +23,8 @@ func TestCreateAnthrovePostNode(t *testing.T) { // Setup Tests validPost := &models.Post{ - BaseModel: models.BaseModel{ - ID: fmt.Sprintf("%025s", "1"), + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), }, Rating: "safe", } @@ -84,8 +84,8 @@ func TestGetPostByAnthroveID(t *testing.T) { // Setup Tests post := &models.Post{ - BaseModel: models.BaseModel{ - ID: fmt.Sprintf("%025s", "1"), + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), }, Rating: "safe", } @@ -112,7 +112,7 @@ func TestGetPostByAnthroveID(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthrovePostID: models.AnthrovePostID(post.ID), + anthrovePostID: post.ID, }, want: post, wantErr: false, @@ -163,8 +163,8 @@ func TestGetPostBySourceURL(t *testing.T) { // Setup Tests post := &models.Post{ - BaseModel: models.BaseModel{ - ID: fmt.Sprintf("%025s", "1"), + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), }, Rating: "safe", } @@ -175,7 +175,9 @@ func TestGetPostBySourceURL(t *testing.T) { } source := models.Source{ - BaseModel: models.BaseModel{ID: fmt.Sprintf("%025s", "1")}, + BaseModel: models.BaseModel[models.AnthroveSourceID]{ + ID: models.AnthroveSourceID(fmt.Sprintf("%025s", "1")), + }, DisplayName: "e621", Domain: "e621.net", Icon: "https://e621.net/icon.ico", @@ -260,8 +262,8 @@ func TestGetPostBySourceID(t *testing.T) { // Setup Tests post := &models.Post{ - BaseModel: models.BaseModel{ - ID: fmt.Sprintf("%025s", "1"), + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), }, Rating: "safe", } @@ -272,7 +274,9 @@ func TestGetPostBySourceID(t *testing.T) { } source := models.Source{ - BaseModel: models.BaseModel{ID: fmt.Sprintf("%025s", "1")}, + BaseModel: models.BaseModel[models.AnthroveSourceID]{ + ID: models.AnthroveSourceID(fmt.Sprintf("%025s", "1")), + }, DisplayName: "e621", Domain: "e621.net", Icon: "https://e621.net/icon.ico", @@ -283,7 +287,7 @@ func TestGetPostBySourceID(t *testing.T) { t.Fatal("Could not create source", err) } - err = CreateReferenceBetweenPostAndSource(ctx, gormDB, models.AnthrovePostID(post.ID), models.AnthroveSourceDomain(source.Domain)) + err = CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain)) if err != nil { t.Fatal("Could not create source reference", err) } @@ -306,7 +310,7 @@ func TestGetPostBySourceID(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - sourceID: models.AnthroveSourceID(source.ID), + sourceID: source.ID, }, want: post, wantErr: false, diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index f719704..b52f37e 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -20,7 +20,7 @@ func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthr // Establish the relationship err = db.WithContext(ctx).Create(models.PostReference{ PostID: string(anthrovePostID), - SourceID: source.ID, + SourceID: string(source.ID), URL: string(sourceDomain), }).Error diff --git a/internal/postgres/relationships_test.go b/internal/postgres/relationships_test.go index cc763a0..e56b461 100644 --- a/internal/postgres/relationships_test.go +++ b/internal/postgres/relationships_test.go @@ -26,8 +26,8 @@ func TestCheckUserToPostLink(t *testing.T) { } post := &models.Post{ - BaseModel: models.BaseModel{ - ID: fmt.Sprintf("%025s", "1"), + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), }, Rating: "safe", } @@ -61,7 +61,7 @@ func TestCheckUserToPostLink(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "1", - anthrovePostID: models.AnthrovePostID(post.ID), + anthrovePostID: post.ID, }, want: true, wantErr: false, @@ -83,7 +83,7 @@ func TestCheckUserToPostLink(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "123", - anthrovePostID: models.AnthrovePostID(post.ID), + anthrovePostID: post.ID, }, want: false, wantErr: false, @@ -125,8 +125,8 @@ func TestEstablishAnthrovePostToSourceLink(t *testing.T) { // Setup Test post := &models.Post{ - BaseModel: models.BaseModel{ - ID: fmt.Sprintf("%025s", "1"), + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), }, Rating: "safe", } @@ -164,7 +164,7 @@ func TestEstablishAnthrovePostToSourceLink(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthrovePostID: models.AnthrovePostID(post.ID), + anthrovePostID: post.ID, sourceDomain: "e621.net", }, wantErr: false, @@ -225,8 +225,8 @@ func TestEstablishUserToPostLink(t *testing.T) { } post := &models.Post{ - BaseModel: models.BaseModel{ - ID: fmt.Sprintf("%025s", "1"), + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), }, Rating: "safe", } @@ -254,7 +254,7 @@ func TestEstablishUserToPostLink(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "1", - anthrovePostID: models.AnthrovePostID(post.ID), + anthrovePostID: post.ID, }, wantErr: false, }, diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index a20b352..d0aa2e0 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -35,8 +35,8 @@ func CreateTagAndReferenceToPost(ctx context.Context, db *gorm.DB, PostID models } pgPost := models.Post{ - BaseModel: models.BaseModel{ - ID: string(PostID), + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: PostID, }, } diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index bc94c77..a100774 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -21,8 +21,8 @@ func TestCreateTagNodeWitRelation(t *testing.T) { // Setup Test post := &models.Post{ - BaseModel: models.BaseModel{ - ID: fmt.Sprintf("%025s", "1"), + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), }, Rating: "safe", } diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 9cdc2da..359533f 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -15,8 +15,8 @@ func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Anthrove } user := models.User{ - BaseModel: models.BaseModel{ - ID: string(anthroveUserID), + BaseModel: models.BaseModel[models.AnthroveUserID]{ + ID: anthroveUserID, }, } @@ -51,7 +51,7 @@ func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUs } source := models.Source{ - BaseModel: models.BaseModel{ID: string(sourceID)}, + BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: sourceID}, } if err := db.WithContext(ctx).Where(&source).First(&source).Error; err != nil { @@ -62,8 +62,8 @@ func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUs } userSource := models.UserSource{ - User: models.User{BaseModel: models.BaseModel{ID: string(anthroveUserID)}}, - SourceID: source.ID, + User: models.User{BaseModel: models.BaseModel[models.AnthroveUserID]{ID: anthroveUserID}}, + SourceID: string(source.ID), AccountUsername: accountUsername, AccountID: accountId, UserID: string(anthroveUserID), @@ -248,7 +248,7 @@ func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUse favoritePosts = append(favoritePosts, models.Post{ - BaseModel: models.BaseModel{ID: post.ID}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: post.ID}, Rating: post.Rating, }) } diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index 6a701da..1983612 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -72,7 +72,9 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { // Setup Test source := &models.Source{ - BaseModel: models.BaseModel{ID: fmt.Sprintf("%025s", "1")}, + BaseModel: models.BaseModel[models.AnthroveSourceID]{ + ID: models.AnthroveSourceID(fmt.Sprintf("%025s", "1")), + }, DisplayName: "e621", Domain: "e621.net", Icon: "icon.e621.net", @@ -102,7 +104,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "1", - sourceID: models.AnthroveSourceID(source.ID), + sourceID: source.ID, userID: "e1", username: "marius", }, @@ -114,7 +116,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "2", - sourceID: models.AnthroveSourceID(source.ID), + sourceID: source.ID, userID: "e1", username: "marius", }, @@ -126,7 +128,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "", - sourceID: models.AnthroveSourceID(source.ID), + sourceID: source.ID, userID: "e1", username: "marius", }, @@ -150,7 +152,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "1", - sourceID: models.AnthroveSourceID(source.ID), + sourceID: source.ID, userID: "", username: "marius", }, @@ -162,7 +164,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "1", - sourceID: models.AnthroveSourceID(source.ID), + sourceID: source.ID, userID: "aa", username: "", }, @@ -255,7 +257,9 @@ func TestGetUserSourceBySourceID(t *testing.T) { } source := &models.Source{ - BaseModel: models.BaseModel{ID: expectedResult["e621"].Source.ID}, + BaseModel: models.BaseModel[models.AnthroveSourceID]{ + ID: expectedResult["e621"].Source.ID, + }, DisplayName: expectedResult["e621"].Source.DisplayName, Domain: expectedResult["e621"].Source.Domain, } @@ -289,7 +293,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "1", - sourceID: models.AnthroveSourceID(source.ID), + sourceID: source.ID, }, want: expectedResult, wantErr: false, @@ -300,7 +304,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "22", - sourceID: models.AnthroveSourceID(source.ID), + sourceID: source.ID, }, want: nil, wantErr: true, @@ -322,7 +326,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { ctx: ctx, db: gormDB, anthroveUserID: "", - sourceID: models.AnthroveSourceID(source.ID), + sourceID: source.ID, }, want: nil, wantErr: true, @@ -377,28 +381,28 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { expectedResultPosts := []models.Post{ { - BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post1")}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post1"))}, Rating: "safe", }, { - BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post2")}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post2"))}, Rating: "safe", }, { - BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post3")}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post3"))}, Rating: "explicit", }, { - BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post4")}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post4"))}, Rating: "explicit", }, { - BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post5")}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post5"))}, Rating: "questionable", }, { - BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post6")}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post6"))}, Rating: "safe", }, } @@ -511,27 +515,27 @@ func TestGetUserFavoritesCount(t *testing.T) { expectedResultPosts := []models.Post{ { - BaseModel: models.BaseModel{ID: "Post1"}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: "Post1"}, Rating: "safe", }, { - BaseModel: models.BaseModel{ID: "Post2"}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: "Post2"}, Rating: "safe", }, { - BaseModel: models.BaseModel{ID: "Post3"}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: "Post3"}, Rating: "explicit", }, { - BaseModel: models.BaseModel{ID: "Post4"}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: "Post4"}, Rating: "explicit", }, { - BaseModel: models.BaseModel{ID: "Post5"}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: "Post5"}, Rating: "questionable", }, { - BaseModel: models.BaseModel{ID: "Post6"}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: "Post6"}, Rating: "safe", }, } @@ -615,7 +619,7 @@ func TestGetUserSourceLinks(t *testing.T) { // Setup Test eSource := &models.Source{ - BaseModel: models.BaseModel{ID: fmt.Sprintf("%025s", "1")}, + BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: models.AnthroveSourceID(fmt.Sprintf("%025s", "1"))}, DisplayName: "e621", Domain: "e621.net", } @@ -625,7 +629,7 @@ func TestGetUserSourceLinks(t *testing.T) { } faSource := &models.Source{ - BaseModel: models.BaseModel{ID: fmt.Sprintf("%025s", "2")}, + BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: models.AnthroveSourceID(fmt.Sprintf("%025s", "2"))}, DisplayName: "fa", Domain: "fa.net", } @@ -652,11 +656,11 @@ func TestGetUserSourceLinks(t *testing.T) { }, } - err = CreateUserWithRelationToSource(ctx, gormDB, "1", models.AnthroveSourceID(eSource.ID), expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) + err = CreateUserWithRelationToSource(ctx, gormDB, "1", eSource.ID, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) if err != nil { t.Fatal(err) } - err = CreateUserWithRelationToSource(ctx, gormDB, "1", models.AnthroveSourceID(faSource.ID), expectedResult["fa"].UserID, expectedResult["fa"].AccountUsername) + err = CreateUserWithRelationToSource(ctx, gormDB, "1", faSource.ID, expectedResult["fa"].UserID, expectedResult["fa"].AccountUsername) if err != nil { t.Fatal(err) } @@ -714,9 +718,9 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { } posts := []models.Post{ - {BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post1")}, Rating: "safe"}, - {BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post2")}, Rating: "safe"}, - {BaseModel: models.BaseModel{ID: fmt.Sprintf("%-25s", "Post3")}, Rating: "explicit"}, + {BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post1"))}, Rating: "safe"}, + {BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post2"))}, Rating: "safe"}, + {BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post3"))}, Rating: "explicit"}, } for _, post := range posts { @@ -737,7 +741,7 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { } for i, tag := range tags { - err = CreateTagAndReferenceToPost(ctx, gormDB, models.AnthrovePostID(posts[i].ID), &tag) + err = CreateTagAndReferenceToPost(ctx, gormDB, posts[i].ID, &tag) if err != nil { t.Fatal(err) } diff --git a/pkg/models/post.go b/pkg/models/post.go index 9aef5e7..bfe9946 100644 --- a/pkg/models/post.go +++ b/pkg/models/post.go @@ -2,7 +2,7 @@ package models // Post model type Post struct { - BaseModel + BaseModel[AnthrovePostID] Rating Rating `gorm:"type:enum('safe','questionable','explicit')"` Tags []Tag `gorm:"many2many:post_tags;"` Favorites []UserFavorites `gorm:"foreignKey:PostID"` diff --git a/pkg/models/source.go b/pkg/models/source.go index 0860b81..200b48e 100644 --- a/pkg/models/source.go +++ b/pkg/models/source.go @@ -2,7 +2,7 @@ package models // Source model type Source struct { - BaseModel + BaseModel[AnthroveSourceID] DisplayName string Domain string `gorm:"not null;unique"` Icon string `gorm:"not null"` diff --git a/pkg/models/user.go b/pkg/models/user.go index 7f723e6..95ba75d 100644 --- a/pkg/models/user.go +++ b/pkg/models/user.go @@ -2,7 +2,7 @@ package models // User model type User struct { - BaseModel + BaseModel[AnthroveUserID] Favorites []UserFavorites `gorm:"foreignKey:UserID"` Sources []UserSource `gorm:"foreignKey:UserID"` } -- 2.45.1 From c0cae140f12bc978e0a6a87171e9d545406f804e Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 25 Jun 2024 14:50:56 +0200 Subject: [PATCH 083/124] test(postgres): finished test migrations to generic orm base Signed-off-by: SoXX --- pkg/database/postgres_test.go | 55 ++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index d14a354..f4cd28f 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -3,10 +3,11 @@ package database import ( "context" "fmt" + "testing" + "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/test" - "testing" ) func TestNewPostgresqlConnection(t *testing.T) { @@ -96,7 +97,7 @@ func Test_postgresqlConnection_CreateUserWithRelationToSource(t *testing.T) { // Setup Test source := &models.Source{ - BaseModel: models.BaseModel{ID: fmt.Sprintf("%025s", "1")}, + BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: models.AnthroveSourceID(fmt.Sprintf("%025s", "1"))}, DisplayName: "e621", Domain: "e621.net", Icon: "icon.e621.net", @@ -124,7 +125,7 @@ func Test_postgresqlConnection_CreateUserWithRelationToSource(t *testing.T) { args: args{ ctx: ctx, anthroveUserID: "1", - sourceID: models.AnthroveSourceID(source.ID), + sourceID: source.ID, accountId: "e1", accountUsername: "marius", }, @@ -135,7 +136,7 @@ func Test_postgresqlConnection_CreateUserWithRelationToSource(t *testing.T) { args: args{ ctx: ctx, anthroveUserID: "2", - sourceID: models.AnthroveSourceID(source.ID), + sourceID: source.ID, accountId: "e1", accountUsername: "marius", }, @@ -146,7 +147,7 @@ func Test_postgresqlConnection_CreateUserWithRelationToSource(t *testing.T) { args: args{ ctx: ctx, anthroveUserID: "", - sourceID: models.AnthroveSourceID(source.ID), + sourceID: source.ID, accountId: "e1", accountUsername: "marius", }, @@ -168,7 +169,7 @@ func Test_postgresqlConnection_CreateUserWithRelationToSource(t *testing.T) { args: args{ ctx: ctx, anthroveUserID: "1", - sourceID: models.AnthroveSourceID(source.ID), + sourceID: source.ID, accountId: "", accountUsername: "marius", }, @@ -179,7 +180,7 @@ func Test_postgresqlConnection_CreateUserWithRelationToSource(t *testing.T) { args: args{ ctx: ctx, anthroveUserID: "1", - sourceID: models.AnthroveSourceID(source.ID), + sourceID: source.ID, accountId: "aa", accountUsername: "", }, @@ -280,8 +281,8 @@ func Test_postgresqlConnection_CreatePost(t *testing.T) { // Setup Tests validPost := &models.Post{ - BaseModel: models.BaseModel{ - ID: fmt.Sprintf("%025s", "1"), + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), }, Rating: "safe", } @@ -342,8 +343,8 @@ func Test_postgresqlConnection_CreateTagAndReferenceToPost(t *testing.T) { // Setup Test post := &models.Post{ - BaseModel: models.BaseModel{ - ID: fmt.Sprintf("%025s", "1"), + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), }, Rating: "safe", } @@ -373,7 +374,7 @@ func Test_postgresqlConnection_CreateTagAndReferenceToPost(t *testing.T) { name: "Test 1: Valid PostID and Tag", args: args{ ctx: ctx, - anthrovePostID: models.AnthrovePostID(post.ID), + anthrovePostID: post.ID, anthroveTag: tag, }, wantErr: false, @@ -382,7 +383,7 @@ func Test_postgresqlConnection_CreateTagAndReferenceToPost(t *testing.T) { name: "Test 2: Valid PostID and no Tag", args: args{ ctx: ctx, - anthrovePostID: models.AnthrovePostID(post.ID), + anthrovePostID: post.ID, anthroveTag: nil, }, wantErr: true, @@ -430,8 +431,8 @@ func Test_postgresqlConnection_CreateReferenceBetweenPostAndSource(t *testing.T) // Setup Test post := &models.Post{ - BaseModel: models.BaseModel{ - ID: fmt.Sprintf("%025s", "1"), + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), }, Rating: "safe", } @@ -466,7 +467,7 @@ func Test_postgresqlConnection_CreateReferenceBetweenPostAndSource(t *testing.T) name: "Test 1: Valid AnthrovePostID and anthroveSourceDomain", args: args{ ctx: ctx, - anthrovePostID: models.AnthrovePostID(post.ID), + anthrovePostID: post.ID, sourceDomain: "e621.net", }, wantErr: false, @@ -527,8 +528,8 @@ func Test_postgresqlConnection_CreateReferenceBetweenUserAndPost(t *testing.T) { } post := &models.Post{ - BaseModel: models.BaseModel{ - ID: fmt.Sprintf("%025s", "1"), + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), }, Rating: "safe", } @@ -554,7 +555,7 @@ func Test_postgresqlConnection_CreateReferenceBetweenUserAndPost(t *testing.T) { args: args{ ctx: ctx, anthroveUserID: "1", - anthrovePostID: models.AnthrovePostID(post.ID), + anthrovePostID: post.ID, }, wantErr: false, }, @@ -615,8 +616,8 @@ func Test_postgresqlConnection_CheckReferenceBetweenUserAndPost(t *testing.T) { } post := &models.Post{ - BaseModel: models.BaseModel{ - ID: fmt.Sprintf("%025s", "1"), + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), }, Rating: "safe", } @@ -626,7 +627,7 @@ func Test_postgresqlConnection_CheckReferenceBetweenUserAndPost(t *testing.T) { t.Fatal(err) } - err = postgres.CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", models.AnthrovePostID(post.ID)) + err = postgres.CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", post.ID) if err != nil { t.Fatal(err) } @@ -648,7 +649,7 @@ func Test_postgresqlConnection_CheckReferenceBetweenUserAndPost(t *testing.T) { args: args{ ctx: ctx, anthroveUserID: "1", - anthrovePostID: models.AnthrovePostID(post.ID), + anthrovePostID: post.ID, }, want: true, wantErr: false, @@ -668,7 +669,7 @@ func Test_postgresqlConnection_CheckReferenceBetweenUserAndPost(t *testing.T) { args: args{ ctx: ctx, anthroveUserID: "123", - anthrovePostID: models.AnthrovePostID(post.ID), + anthrovePostID: post.ID, }, want: false, wantErr: false, @@ -714,8 +715,8 @@ func Test_postgresqlConnection_GetPostByAnthroveID(t *testing.T) { // Setup Tests post := &models.Post{ - BaseModel: models.BaseModel{ - ID: fmt.Sprintf("%025s", "1"), + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), }, Rating: "safe", } @@ -740,7 +741,7 @@ func Test_postgresqlConnection_GetPostByAnthroveID(t *testing.T) { name: "Test 1: Valid anthrovePostID", args: args{ ctx: ctx, - anthrovePost: models.AnthrovePostID(post.ID), + anthrovePost: post.ID, }, want: post, wantErr: false, -- 2.45.1 From d3c05992633050d701ea15f0a20b12ca58a50b69 Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 25 Jun 2024 14:55:25 +0200 Subject: [PATCH 084/124] ci: disable check for latest go Signed-off-by: SoXX --- .gitea/workflows/ build_check.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/ build_check.yaml b/.gitea/workflows/ build_check.yaml index 193bcfd..f0e769d 100644 --- a/.gitea/workflows/ build_check.yaml +++ b/.gitea/workflows/ build_check.yaml @@ -23,7 +23,7 @@ jobs: # Path to the go.mod file. go-version-file: ./go.mod # optional # Set this option to true if you want the action to always check for the latest available version that satisfies the version spec - check-latest: true # optional + check-latest: false # optional # Used to specify whether caching is needed. Set to true, if you'd like to enable caching. cache: true # optional -- 2.45.1 From d8f338332b36cd68deb6579ab1c38354535f5d67 Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 25 Jun 2024 14:56:08 +0200 Subject: [PATCH 085/124] ci: disable cache Signed-off-by: SoXX --- .gitea/workflows/ build_check.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/ build_check.yaml b/.gitea/workflows/ build_check.yaml index f0e769d..92dbbf8 100644 --- a/.gitea/workflows/ build_check.yaml +++ b/.gitea/workflows/ build_check.yaml @@ -25,7 +25,7 @@ jobs: # Set this option to true if you want the action to always check for the latest available version that satisfies the version spec check-latest: false # optional # Used to specify whether caching is needed. Set to true, if you'd like to enable caching. - cache: true # optional + cache: false # optional - name: Execute Go Test files with coverage report run: go test -v ./... -json -coverprofile="coverage.out" > "test-report.out" -- 2.45.1 From 07b69f6c1823653c0cee4bd5d52442a684671ee5 Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 25 Jun 2024 15:00:44 +0200 Subject: [PATCH 086/124] test(postgres): fixed to use new ORM Generic Signed-off-by: SoXX --- pkg/models/orm_test.go | 7 ++++--- pkg/models/post_test.go | 2 +- pkg/models/source_test.go | 2 +- pkg/models/user_test.go | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/pkg/models/orm_test.go b/pkg/models/orm_test.go index d18fd2b..cf9e1a4 100644 --- a/pkg/models/orm_test.go +++ b/pkg/models/orm_test.go @@ -1,9 +1,10 @@ package models import ( - "gorm.io/gorm" "testing" "time" + + "gorm.io/gorm" ) func TestBaseModel_BeforeCreate(t *testing.T) { @@ -41,8 +42,8 @@ func TestBaseModel_BeforeCreate(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - base := &BaseModel{ - ID: tt.fields.ID, + base := &BaseModel[AnthrovePostID]{ + ID: AnthrovePostID(tt.fields.ID), CreatedAt: tt.fields.CreatedAt, UpdatedAt: tt.fields.UpdatedAt, DeletedAt: tt.fields.DeletedAt, diff --git a/pkg/models/post_test.go b/pkg/models/post_test.go index c90852e..2e7228d 100644 --- a/pkg/models/post_test.go +++ b/pkg/models/post_test.go @@ -4,7 +4,7 @@ import "testing" func TestPost_TableName(t *testing.T) { type fields struct { - BaseModel BaseModel + BaseModel BaseModel[AnthrovePostID] Rating Rating Tags []Tag Favorites []UserFavorites diff --git a/pkg/models/source_test.go b/pkg/models/source_test.go index 1a5ff8c..e65b2c8 100644 --- a/pkg/models/source_test.go +++ b/pkg/models/source_test.go @@ -4,7 +4,7 @@ import "testing" func TestSource_TableName(t *testing.T) { type fields struct { - BaseModel BaseModel + BaseModel BaseModel[AnthroveSourceID] DisplayName string Domain string Icon string diff --git a/pkg/models/user_test.go b/pkg/models/user_test.go index fa2c511..c31745b 100644 --- a/pkg/models/user_test.go +++ b/pkg/models/user_test.go @@ -4,7 +4,7 @@ import "testing" func TestUser_TableName(t *testing.T) { type fields struct { - BaseModel BaseModel + BaseModel BaseModel[AnthroveUserID] Favorites []UserFavorites Sources []UserSource } -- 2.45.1 From 819dc7055afb2c149b91f0954b43eb990b3bec0b Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 25 Jun 2024 15:09:39 +0200 Subject: [PATCH 087/124] feat(postgres): updated go mod Signed-off-by: SoXX --- go.mod | 6 ------ go.sum | 4 ---- 2 files changed, 10 deletions(-) diff --git a/go.mod b/go.mod index a25e991..fe9ef40 100644 --- a/go.mod +++ b/go.mod @@ -3,13 +3,10 @@ module git.dragse.it/anthrove/otter-space-sdk go 1.22.0 require ( - github.com/brianvoe/gofakeit/v7 v7.0.3 github.com/lib/pq v1.10.9 github.com/matoous/go-nanoid/v2 v2.1.0 - github.com/neo4j/neo4j-go-driver/v5 v5.17.0 github.com/rubenv/sql-migrate v1.6.1 github.com/sirupsen/logrus v1.9.3 - github.com/stretchr/testify v1.9.0 github.com/testcontainers/testcontainers-go v0.31.0 github.com/testcontainers/testcontainers-go/modules/postgres v0.31.0 gorm.io/driver/postgres v1.5.7 @@ -25,7 +22,6 @@ require ( github.com/containerd/containerd v1.7.15 // indirect github.com/containerd/log v0.1.0 // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect github.com/distribution/reference v0.5.0 // indirect github.com/docker/docker v25.0.5+incompatible // indirect github.com/docker/go-connections v0.5.0 // indirect @@ -55,7 +51,6 @@ require ( github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/shirou/gopsutil/v3 v3.23.12 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect @@ -75,5 +70,4 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d // indirect google.golang.org/grpc v1.58.3 // indirect google.golang.org/protobuf v1.33.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 3b9b10a..a54ced4 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,6 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= -github.com/brianvoe/gofakeit/v7 v7.0.3 h1:tGCt+eYfhTMWE1ko5G2EO1f/yE44yNpIwUb4h32O0wo= -github.com/brianvoe/gofakeit/v7 v7.0.3/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/containerd/containerd v1.7.15 h1:afEHXdil9iAm03BmhjzKyXnnEBtjaLJefdU7DV0IFes= @@ -96,8 +94,6 @@ github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/neo4j/neo4j-go-driver/v5 v5.17.0 h1:Bdqg1Y8Hd3uLYToXtBjysDYXTdMiP7zeUNUEwfbJkSo= -github.com/neo4j/neo4j-go-driver/v5 v5.17.0/go.mod h1:Vff8OwT7QpLm7L2yYr85XNWe9Rbqlbeb9asNXJTHO4k= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -- 2.45.1 From f34cc637ec9e6a0099b7aaa80614a19d8ee34e28 Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 25 Jun 2024 15:11:47 +0200 Subject: [PATCH 088/124] ci: readable cache and check for latest Signed-off-by: SoXX --- .gitea/workflows/ build_check.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/ build_check.yaml b/.gitea/workflows/ build_check.yaml index 92dbbf8..193bcfd 100644 --- a/.gitea/workflows/ build_check.yaml +++ b/.gitea/workflows/ build_check.yaml @@ -23,9 +23,9 @@ jobs: # Path to the go.mod file. go-version-file: ./go.mod # optional # Set this option to true if you want the action to always check for the latest available version that satisfies the version spec - check-latest: false # optional + check-latest: true # optional # Used to specify whether caching is needed. Set to true, if you'd like to enable caching. - cache: false # optional + cache: true # optional - name: Execute Go Test files with coverage report run: go test -v ./... -json -coverprofile="coverage.out" > "test-report.out" -- 2.45.1 From c246f661ff8655cd660bc630f98a146d0b9dac2b Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 25 Jun 2024 15:13:52 +0200 Subject: [PATCH 089/124] ci: update version of steps Signed-off-by: SoXX --- .gitea/workflows/ build_check.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/ build_check.yaml b/.gitea/workflows/ build_check.yaml index 193bcfd..5a50130 100644 --- a/.gitea/workflows/ build_check.yaml +++ b/.gitea/workflows/ build_check.yaml @@ -11,12 +11,12 @@ jobs: Build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Setup Go environment - uses: https://github.com/actions/setup-go@v3 + uses: https://github.com/actions/setup-go@v5 with: # The Go version to download (if necessary) and use. Supports semver spec and ranges. go-version: 1.22.0 # optional -- 2.45.1 From 63e74219ed245b6eabe1c5d8baec540d8aba31da Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 25 Jun 2024 16:02:08 +0200 Subject: [PATCH 090/124] feat(error): added first steps for custom errors Signed-off-by: SoXX --- error/database.go | 19 +++++++++++++++++++ error/validation.go | 7 +++++++ internal/postgres/post.go | 26 ++++++++++++++++++-------- 3 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 error/database.go create mode 100644 error/validation.go diff --git a/error/database.go b/error/database.go new file mode 100644 index 0000000..c842614 --- /dev/null +++ b/error/database.go @@ -0,0 +1,19 @@ +package error + +type EntityAlreadyExists struct{} + +type NoDataWritten struct{} + +type NoDataFound struct{} + +func (e *EntityAlreadyExists) Error() string { + return "EntityAlreadyExists error" +} + +func (e *NoDataWritten) Error() string { + return "NoDataWritten error" +} + +func (e *NoDataFound) Error() string { + return "NoDataFound error" +} diff --git a/error/validation.go b/error/validation.go new file mode 100644 index 0000000..b6b4245 --- /dev/null +++ b/error/validation.go @@ -0,0 +1,7 @@ +package error + +type MissingAnthrovePostIDError struct{} + +func (e *MissingAnthrovePostIDError) Error() string { + return "AnthrovePostID is empty" +} diff --git a/internal/postgres/post.go b/internal/postgres/post.go index 2dde49a..ffe74be 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -3,16 +3,24 @@ package postgres import ( "context" "errors" - "fmt" + + error2 "git.dragse.it/anthrove/otter-space-sdk/error" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) func CreatePost(ctx context.Context, db *gorm.DB, anthrovePost *models.Post) error { - err := db.WithContext(ctx).Create(&anthrovePost).Error - if err != nil { - return err + result := db.WithContext(ctx).Create(&anthrovePost) + + if result.RowsAffected == 0 { + return &error2.NoDataWritten{} + } + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrDuplicatedKey) { + return &error2.EntityAlreadyExists{} + } } log.WithFields(log.Fields{ @@ -25,13 +33,15 @@ func CreatePost(ctx context.Context, db *gorm.DB, anthrovePost *models.Post) err func GetPostByAnthroveID(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID) (*models.Post, error) { if anthrovePostID == "" { - return nil, fmt.Errorf("anthrovePostID is required") + return nil, &error2.MissingAnthrovePostIDError{} } var post models.Post - err := db.WithContext(ctx).First(&post, "id = ?", anthrovePostID).Error - if err != nil { - return nil, err + result := db.WithContext(ctx).First(&post, "id = ?", anthrovePostID) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &error2.NoDataFound{} + } } return &post, nil -- 2.45.1 From d94ae83c2f52692b573ec38c5b5ce9650993ec33 Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 25 Jun 2024 21:55:43 +0200 Subject: [PATCH 091/124] feat(errors): implemented custom errors Signed-off-by: SoXX --- error/validation.go | 7 - internal/postgres/post.go | 57 ++++--- internal/postgres/relationships.go | 87 +++++++++-- internal/postgres/source.go | 20 ++- internal/postgres/tag.go | 46 ++++-- internal/postgres/user.go | 230 ++++++++++++++++++----------- {error => pkg/errors}/database.go | 16 +- pkg/errors/validation.go | 11 ++ 8 files changed, 324 insertions(+), 150 deletions(-) delete mode 100644 error/validation.go rename {error => pkg/errors}/database.go (70%) create mode 100644 pkg/errors/validation.go diff --git a/error/validation.go b/error/validation.go deleted file mode 100644 index b6b4245..0000000 --- a/error/validation.go +++ /dev/null @@ -1,7 +0,0 @@ -package error - -type MissingAnthrovePostIDError struct{} - -func (e *MissingAnthrovePostIDError) Error() string { - return "AnthrovePostID is empty" -} diff --git a/internal/postgres/post.go b/internal/postgres/post.go index ffe74be..2206e00 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -3,24 +3,29 @@ package postgres import ( "context" "errors" + errors2 "git.dragse.it/anthrove/otter-space-sdk/pkg/errors" - error2 "git.dragse.it/anthrove/otter-space-sdk/error" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) func CreatePost(ctx context.Context, db *gorm.DB, anthrovePost *models.Post) error { - result := db.WithContext(ctx).Create(&anthrovePost) - if result.RowsAffected == 0 { - return &error2.NoDataWritten{} + if anthrovePost == nil { + return &errors2.EntityValidationFailed{Reason: "anthrovePost is nil"} } + result := db.WithContext(ctx).Create(&anthrovePost) if result.Error != nil { if errors.Is(result.Error, gorm.ErrDuplicatedKey) { - return &error2.EntityAlreadyExists{} + return &errors2.EntityAlreadyExists{} } + return result.Error + } + + if result.RowsAffected == 0 { + return &errors2.NoDataWritten{} } log.WithFields(log.Fields{ @@ -32,44 +37,58 @@ func CreatePost(ctx context.Context, db *gorm.DB, anthrovePost *models.Post) err } func GetPostByAnthroveID(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID) (*models.Post, error) { + if anthrovePostID == "" { - return nil, &error2.MissingAnthrovePostIDError{} + return nil, &errors2.EntityValidationFailed{Reason: "anthrovePostID is not set"} } + //TODO maybe check ofor id length too...? + var post models.Post result := db.WithContext(ctx).First(&post, "id = ?", anthrovePostID) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &error2.NoDataFound{} + return nil, &errors2.NoDataFound{} } + return nil, result.Error } return &post, nil } func GetPostByURL(ctx context.Context, db *gorm.DB, sourceURL string) (*models.Post, error) { - var post models.Post - err := db.WithContext(ctx).Raw(`SELECT p.id AS id, p.rating as rating FROM "Post" AS p INNER JOIN "PostReference" AS pr ON p.id = pr.post_id AND pr.url = $1 LIMIT 1`, sourceURL).First(&post).Error - if err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - return nil, nil + if sourceURL == "" { + return nil, &errors2.EntityValidationFailed{Reason: "sourceURL is not set"} + } + + var post models.Post + result := db.WithContext(ctx).Raw(`SELECT p.id AS id, p.rating as rating FROM "Post" AS p INNER JOIN "PostReference" AS pr ON p.id = pr.post_id AND pr.url = $1 LIMIT 1`, sourceURL).First(&post) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &errors2.NoDataFound{} } - return nil, err + return nil, result.Error } return &post, nil } func GetPostBySourceID(ctx context.Context, db *gorm.DB, sourceID models.AnthroveSourceID) (*models.Post, error) { - var post models.Post - err := db.WithContext(ctx).Raw(`SELECT p.id AS id, p.rating as rating FROM "Post" AS p INNER JOIN "PostReference" AS pr ON p.id = pr.post_id AND pr.source_id = $1 LIMIT 1`, sourceID).First(&post).Error - if err != nil { - if errors.Is(err, gorm.ErrRecordNotFound) { - return nil, nil + if sourceID == "" { + return nil, &errors2.EntityValidationFailed{Reason: "sourceID is not set"} + } + + var post models.Post + result := db.WithContext(ctx).Raw(`SELECT p.id AS id, p.rating as rating FROM "Post" AS p INNER JOIN "PostReference" AS pr ON p.id = pr.post_id AND pr.source_id = $1 LIMIT 1`, sourceID).First(&post) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &errors2.NoDataFound{} } - return nil, err + return nil, result.Error } return &post, nil diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index b52f37e..c072241 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -2,6 +2,8 @@ package postgres import ( "context" + "errors" + errors2 "git.dragse.it/anthrove/otter-space-sdk/pkg/errors" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" log "github.com/sirupsen/logrus" "gorm.io/gorm" @@ -9,23 +11,44 @@ import ( func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain) error { var source models.Source - var err error + + if anthrovePostID == "" { + return &errors2.EntityValidationFailed{Reason: "anthrovePostID cannot be empty"} + } + + if len(anthrovePostID) != 25 { + return &errors2.EntityValidationFailed{Reason: "anthrovePostID needs to be 25 characters long"} + } + + if sourceDomain == "" { + return &errors2.EntityValidationFailed{Reason: "sourceDomain cannot be empty"} + } // Find the source - err = db.WithContext(ctx).Where("domain = ?", sourceDomain).First(&source).Error - if err != nil { - return err + result := db.WithContext(ctx).Where("domain = ?", sourceDomain).First(&source) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return &errors2.NoDataFound{} + } + return result.Error } // Establish the relationship - err = db.WithContext(ctx).Create(models.PostReference{ + result = db.WithContext(ctx).Create(models.PostReference{ PostID: string(anthrovePostID), SourceID: string(source.ID), URL: string(sourceDomain), - }).Error + }) - if err != nil { - return err + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrDuplicatedKey) { + return &errors2.EntityAlreadyExists{} + } + return result.Error + } + + if result.RowsAffected == 0 { + return &errors2.NoDataWritten{} } log.WithFields(log.Fields{ @@ -37,14 +60,34 @@ func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthr } func CreateReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error { + + if anthrovePostID == "" { + return &errors2.EntityValidationFailed{Reason: "anthrovePostID cannot be empty"} + } + + if len(anthrovePostID) != 25 { + return &errors2.EntityValidationFailed{Reason: "anthrovePostID needs to be 25 characters long"} + } + + if anthroveUserID == "" { + return &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + } + userFavorite := models.UserFavorites{ UserID: string(anthroveUserID), PostID: string(anthrovePostID), } - err := db.WithContext(ctx).Create(&userFavorite).Error - if err != nil { - return err + result := db.WithContext(ctx).Create(&userFavorite) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrDuplicatedKey) { + return &errors2.EntityAlreadyExists{} + } + return result.Error + } + + if result.RowsAffected == 0 { + return &errors2.NoDataWritten{} } log.WithFields(log.Fields{ @@ -57,9 +100,25 @@ func CreateReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthrov func CheckReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) (bool, error) { var count int64 - err := db.WithContext(ctx).Model(&models.UserFavorites{}).Where("user_id = ? AND post_id = ?", string(anthroveUserID), string(anthrovePostID)).Count(&count).Error - if err != nil { - return false, err + + if anthrovePostID == "" { + return false, &errors2.EntityValidationFailed{Reason: "anthrovePostID cannot be empty"} + } + + if len(anthrovePostID) != 25 { + return false, &errors2.EntityValidationFailed{Reason: "anthrovePostID needs to be 25 characters long"} + } + + if anthroveUserID == "" { + return false, &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + } + + result := db.WithContext(ctx).Model(&models.UserFavorites{}).Where("user_id = ? AND post_id = ?", string(anthroveUserID), string(anthrovePostID)).Count(&count) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return false, &errors2.NoDataFound{} + } + return false, result.Error } exists := count > 0 diff --git a/internal/postgres/source.go b/internal/postgres/source.go index da13fc3..1238a87 100644 --- a/internal/postgres/source.go +++ b/internal/postgres/source.go @@ -2,7 +2,8 @@ package postgres import ( "context" - "fmt" + "errors" + errors2 "git.dragse.it/anthrove/otter-space-sdk/pkg/errors" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" log "github.com/sirupsen/logrus" @@ -13,15 +14,22 @@ import ( func CreateSource(ctx context.Context, db *gorm.DB, anthroveSource *models.Source) error { if anthroveSource.Domain == "" { - return fmt.Errorf("anthroveSource domain is required") + return &errors2.EntityValidationFailed{Reason: "Domain is required"} } result := db.WithContext(ctx).Where(models.Source{Domain: anthroveSource.Domain}).FirstOrCreate(anthroveSource) if result.Error != nil { + if errors.Is(result.Error, gorm.ErrDuplicatedKey) { + return &errors2.EntityAlreadyExists{} + } return result.Error } + if result.RowsAffected == 0 { + return &errors2.NoDataWritten{} + } + log.WithFields(log.Fields{ "node_source_url": anthroveSource.Domain, "node_source_displayName": anthroveSource.DisplayName, @@ -38,6 +46,9 @@ func GetAllSource(ctx context.Context, db *gorm.DB) ([]models.Source, error) { result := db.WithContext(ctx).Find(&sources) if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &errors2.NoDataFound{} + } // TODO really...? i don't think this error handling should be here..? / not possible return nil, result.Error } @@ -53,12 +64,15 @@ func GetSourceByDomain(ctx context.Context, db *gorm.DB, sourceDomain models.Ant var sources models.Source if sourceDomain == "" { - return nil, fmt.Errorf("domain is required") + return nil, &errors2.EntityValidationFailed{Reason: "AnthroveSourceDomain is not set"} } result := db.WithContext(ctx).Where("domain = ?", sourceDomain).First(&sources) if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &errors2.NoDataFound{} + } return nil, result.Error } diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index d0aa2e0..248a6a7 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -2,7 +2,8 @@ package postgres import ( "context" - "fmt" + "errors" + errors2 "git.dragse.it/anthrove/otter-space-sdk/pkg/errors" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" log "github.com/sirupsen/logrus" "gorm.io/gorm" @@ -10,10 +11,20 @@ import ( func CreateTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { - resultTag := db.WithContext(ctx).Where(tag).Create(tag) + if tag == nil { + return &errors2.EntityValidationFailed{Reason: "Tag is nil"} + } - if resultTag.Error != nil { - return resultTag.Error + result := db.WithContext(ctx).Where(tag).Create(tag) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrDuplicatedKey) { + return &errors2.EntityAlreadyExists{} + } + return result.Error + } + + if result.RowsAffected == 0 { + return &errors2.NoDataWritten{} } log.WithFields(log.Fields{ @@ -24,30 +35,36 @@ func CreateTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { return nil } -func CreateTagAndReferenceToPost(ctx context.Context, db *gorm.DB, PostID models.AnthrovePostID, tag *models.Tag) error { +func CreateTagAndReferenceToPost(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, tag *models.Tag) error { - if PostID == "" { - return fmt.Errorf("PostID is empty") + if anthrovePostID == "" { + return &errors2.EntityValidationFailed{Reason: "anthrovePostID cannot be empty"} + } + + if len(anthrovePostID) != 25 { + return &errors2.EntityValidationFailed{Reason: "anthrovePostID needs to be 25 characters long"} } if tag == nil { - return fmt.Errorf("tag is nill") + return &errors2.EntityValidationFailed{Reason: "Tag is nil"} } pgPost := models.Post{ BaseModel: models.BaseModel[models.AnthrovePostID]{ - ID: PostID, + ID: anthrovePostID, }, } err := db.WithContext(ctx).Model(&pgPost).Association("Tags").Append(tag) - if err != nil { - return err + if errors.Is(err, gorm.ErrRecordNotFound) { + return &errors2.NoDataFound{} + } + return errors.Join(err, &errors2.NoRelationCreated{}) } log.WithFields(log.Fields{ - "anthrove_post_id": PostID, + "anthrove_post_id": anthrovePostID, "tag_name": tag.Name, "tag_type": tag.Type, }).Trace("database: created tag node") @@ -57,8 +74,13 @@ func CreateTagAndReferenceToPost(ctx context.Context, db *gorm.DB, PostID models func GetTags(ctx context.Context, db *gorm.DB) ([]models.Tag, error) { var tags []models.Tag + result := db.WithContext(ctx).Find(&tags) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { // TODO really...? i don't think this error handling should be here..? / not possible + return nil, &errors2.NoDataFound{} + } return nil, result.Error } diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 359533f..0e4070b 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -2,7 +2,8 @@ package postgres import ( "context" - "fmt" + "errors" + errors2 "git.dragse.it/anthrove/otter-space-sdk/pkg/errors" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" log "github.com/sirupsen/logrus" "gorm.io/gorm" @@ -11,7 +12,11 @@ import ( func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) error { if anthroveUserID == "" { - return fmt.Errorf("anthroveUserID cannot be empty") + return &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + } + + if len(anthroveUserID) != 25 { + return &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} } user := models.User{ @@ -20,12 +25,16 @@ func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Anthrove }, } - err := db.WithContext(ctx).FirstOrCreate(&user).Error - if err != nil { - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - }).Error("database: failed to create user") - return err + result := db.WithContext(ctx).FirstOrCreate(&user) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrDuplicatedKey) { + return &errors2.EntityAlreadyExists{} + } + return result.Error + } + + if result.RowsAffected == 0 { + return &errors2.NoDataWritten{} } return nil @@ -34,15 +43,19 @@ func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Anthrove func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, accountId string, accountUsername string) error { if anthroveUserID == "" { - return fmt.Errorf("anthroveUserID cannot be empty") + return &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + } + + if len(anthroveUserID) != 25 { + return &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} } if accountId == "" { - return fmt.Errorf("account_id cannot be empty") + return &errors2.EntityValidationFailed{Reason: "accountID cannot be empty"} } if accountUsername == "" { - return fmt.Errorf("account_username cannot be empty") + return &errors2.EntityValidationFailed{Reason: "accountUsername cannot be empty"} } err := CreateUser(ctx, db, anthroveUserID) @@ -54,11 +67,12 @@ func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUs BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: sourceID}, } - if err := db.WithContext(ctx).Where(&source).First(&source).Error; err != nil { - log.WithFields(log.Fields{ - "source_id": sourceID, - }).Error("database: failed to find source") - return err + result := db.WithContext(ctx).Where(&source).First(&source) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return &errors2.NoDataFound{} + } + return result.Error } userSource := models.UserSource{ @@ -69,14 +83,13 @@ func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUs UserID: string(anthroveUserID), } - if err := db.WithContext(ctx).FirstOrCreate(&userSource).Error; err != nil { - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - "source_id": sourceID, - "account_username": accountUsername, - "account_id": accountId, - }).Error("database: failed to create user-source relationship") - return err + result = db.WithContext(ctx).FirstOrCreate(&userSource) + if result.Error != nil { + return errors.Join(result.Error, &errors2.NoRelationCreated{}) + } + + if result.RowsAffected == 0 { + return &errors2.NoDataWritten{} } log.WithFields(log.Fields{ @@ -90,17 +103,22 @@ func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUs } func GetUserFavoritesCount(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) (int64, error) { + var count int64 + if anthroveUserID == "" { - return 0, fmt.Errorf("anthroveUserID cannot be empty") + return 0, &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} } - var count int64 - err := db.WithContext(ctx).Model(&models.UserFavorites{}).Where("user_id = ?", string(anthroveUserID)).Count(&count).Error - if err != nil { - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - }).Error("database: failed to get user favorites count") - return 0, err + if len(anthroveUserID) != 25 { + return 0, &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} + } + + result := db.WithContext(ctx).Model(&models.UserFavorites{}).Where("user_id = ?", string(anthroveUserID)).Count(&count) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return 0, &errors2.NoDataFound{} + } + return 0, result.Error } log.WithFields(log.Fields{ @@ -115,22 +133,30 @@ func GetUserSourceLinks(ctx context.Context, db *gorm.DB, anthroveUserID models. var userSources []models.UserSource userSourceMap := make(map[string]models.UserSource) - err := db.WithContext(ctx).Model(&models.UserSource{}).Where("user_id = ?", string(anthroveUserID)).Find(&userSources).Error - if err != nil { - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - }).Error("database: failed to get user source link") - return nil, err + if anthroveUserID == "" { + return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + } + + if len(anthroveUserID) != 25 { + return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} + } + + result := db.WithContext(ctx).Model(&models.UserSource{}).Where("user_id = ?", string(anthroveUserID)).Find(&userSources) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &errors2.NoDataFound{} + } + return nil, result.Error } for _, userSource := range userSources { var source models.Source - err = db.WithContext(ctx).Model(&models.Source{}).Where("id = ?", userSource.SourceID).First(&source).Error - if err != nil { - log.WithFields(log.Fields{ - "source_id": userSource.SourceID, - }).Error("database: failed to get source") - return nil, err + result = db.WithContext(ctx).Model(&models.Source{}).Where("id = ?", userSource.SourceID).First(&source) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &errors2.NoDataFound{} + } + return nil, result.Error } userSourceMap[source.DisplayName] = models.UserSource{ @@ -152,34 +178,41 @@ func GetUserSourceLinks(ctx context.Context, db *gorm.DB, anthroveUserID models. } func GetUserSourceBySourceID(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID) (map[string]models.UserSource, error) { - if anthroveUserID == "" { - return nil, fmt.Errorf("anthroveUserID cannot be empty") - } - - if sourceID == "" { - return nil, fmt.Errorf("sourceID cannot be empty") - } - var userSources []models.UserSource userSourceMap := make(map[string]models.UserSource) - err := db.WithContext(ctx).Model(&models.UserSource{}).InnerJoins("Source", db.Where("id = ?", sourceID)).Where("user_id = ?", string(anthroveUserID)).First(&userSources).Error - if err != nil { - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - "source_id": sourceID, - }).Error("database: failed to get specified user source link") - return nil, err + if anthroveUserID == "" { + return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + } + + if len(anthroveUserID) != 25 { + return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} + } + + if sourceID == "" { + return nil, &errors2.EntityValidationFailed{Reason: "sourceID cannot be empty"} + } + + if len(sourceID) != 25 { + return nil, &errors2.EntityValidationFailed{Reason: "sourceID needs to be 25 characters long"} + } + + result := db.WithContext(ctx).Model(&models.UserSource{}).InnerJoins("Source", db.Where("id = ?", sourceID)).Where("user_id = ?", string(anthroveUserID)).First(&userSources) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &errors2.NoDataFound{} + } + return nil, result.Error } for _, userSource := range userSources { var source models.Source - err = db.WithContext(ctx).Model(&models.Source{}).Where("id = ?", userSource.SourceID).First(&source).Error - if err != nil { - log.WithFields(log.Fields{ - "source_id": userSource.SourceID, - }).Error("database: failed to get source") - return nil, err + result = db.WithContext(ctx).Model(&models.Source{}).Where("id = ?", userSource.SourceID).First(&source) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &errors2.NoDataFound{} + } + return nil, result.Error } userSourceMap[source.DisplayName] = models.UserSource{ @@ -205,14 +238,16 @@ func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveU var users []models.User var userIDs []models.AnthroveUserID - err := db.WithContext(ctx).Model(&models.User{}).Find(&users).Error - if err != nil { - log.Error("database: failed to get all anthrove user IDs") - return nil, err + result := db.WithContext(ctx).Model(&models.User{}).Find(&users) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &errors2.NoDataFound{} + } + return nil, result.Error } for _, user := range users { - userIDs = append(userIDs, models.AnthroveUserID(user.ID)) + userIDs = append(userIDs, user.ID) } log.WithFields(log.Fields{ @@ -226,13 +261,19 @@ func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUse var userFavorites []models.UserFavorites var favoritePosts []models.Post + if anthroveUserID == "" { + return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + } + + if len(anthroveUserID) != 25 { + return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} + } + err := db.WithContext(ctx).Model(&models.UserFavorites{}).Where("user_id = ?", string(anthroveUserID)).Offset(skip).Limit(limit).Find(&userFavorites).Error if err != nil { - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - "skip": skip, - "limit": limit, - }).Error("database: failed to get user favorites with pagination") + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, &errors2.NoDataFound{} + } return nil, err } @@ -240,9 +281,9 @@ func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUse var post models.Post err = db.WithContext(ctx).Model(&models.Post{}).Where("id = ?", userFavorite.PostID).First(&post).Error if err != nil { - log.WithFields(log.Fields{ - "post_id": userFavorite.PostID, - }).Error("database: failed to get post") + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, &errors2.NoDataFound{} + } return nil, err } @@ -263,12 +304,21 @@ func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUse func GetUserTagWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { var userFavorites []models.UserFavorites - err := db.WithContext(ctx).Where("user_id = ?", string(anthroveUserID)).Find(&userFavorites).Error - if err != nil { - log.WithFields(log.Fields{ - "anthrove_user_id": anthroveUserID, - }).Error("database: failed to get user favorites") - return nil, err + + if anthroveUserID == "" { + return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + } + + if len(anthroveUserID) != 25 { + return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} + } + + result := db.WithContext(ctx).Where("user_id = ?", string(anthroveUserID)).Find(&userFavorites) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &errors2.NoDataFound{} + } + return nil, result.Error } tagFrequency := make(map[struct { @@ -278,12 +328,12 @@ func GetUserTagWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthrov for _, userFavorite := range userFavorites { var post models.Post - err = db.WithContext(ctx).Preload("Tags").First(&post, "id = ?", userFavorite.PostID).Error - if err != nil { - log.WithFields(log.Fields{ - "post_id": userFavorite.PostID, - }).Error("database: failed to get post tags") - return nil, err + result = db.WithContext(ctx).Preload("Tags").First(&post, "id = ?", userFavorite.PostID) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &errors2.NoDataFound{} + } + return nil, result.Error } for _, tag := range post.Tags { diff --git a/error/database.go b/pkg/errors/database.go similarity index 70% rename from error/database.go rename to pkg/errors/database.go index c842614..5559b95 100644 --- a/error/database.go +++ b/pkg/errors/database.go @@ -1,19 +1,25 @@ -package error +package errors type EntityAlreadyExists struct{} -type NoDataWritten struct{} - -type NoDataFound struct{} - func (e *EntityAlreadyExists) Error() string { return "EntityAlreadyExists error" } +type NoDataWritten struct{} + func (e *NoDataWritten) Error() string { return "NoDataWritten error" } +type NoDataFound struct{} + func (e *NoDataFound) Error() string { return "NoDataFound error" } + +type NoRelationCreated struct{} + +func (e *NoRelationCreated) Error() string { + return "relationship creation error" +} diff --git a/pkg/errors/validation.go b/pkg/errors/validation.go new file mode 100644 index 0000000..a04ac75 --- /dev/null +++ b/pkg/errors/validation.go @@ -0,0 +1,11 @@ +package errors + +import "fmt" + +type EntityValidationFailed struct { + Reason string +} + +func (e EntityValidationFailed) Error() string { + return fmt.Sprintf("Entity validation failed: %s", e.Reason) +} -- 2.45.1 From f66fc6b6d7a19cd0fd152734d85093b25288d211 Mon Sep 17 00:00:00 2001 From: SoXX Date: Tue, 25 Jun 2024 22:22:05 +0200 Subject: [PATCH 092/124] tests(errors): fix test cases to reflect the new validation and error handling Signed-off-by: SoXX --- internal/postgres/post_test.go | 8 ++--- internal/postgres/relationships.go | 4 +++ internal/postgres/relationships_test.go | 48 +++++++++++++++---------- internal/postgres/source_test.go | 6 +++- internal/postgres/user_test.go | 42 +++++++++++++++------- 5 files changed, 72 insertions(+), 36 deletions(-) diff --git a/internal/postgres/post_test.go b/internal/postgres/post_test.go index 389e339..1b1bc83 100644 --- a/internal/postgres/post_test.go +++ b/internal/postgres/post_test.go @@ -223,7 +223,7 @@ func TestGetPostBySourceURL(t *testing.T) { sourceURL: "1234", }, want: nil, - wantErr: false, + wantErr: true, }, { name: "Test 3: No sourceURL", @@ -233,7 +233,7 @@ func TestGetPostBySourceURL(t *testing.T) { sourceURL: "", }, want: nil, - wantErr: false, + wantErr: true, }, } for _, tt := range tests { @@ -323,7 +323,7 @@ func TestGetPostBySourceID(t *testing.T) { sourceID: "1234", }, want: nil, - wantErr: false, + wantErr: true, }, { name: "Test 3: No sourceID", @@ -333,7 +333,7 @@ func TestGetPostBySourceID(t *testing.T) { sourceID: "", }, want: nil, - wantErr: false, + wantErr: true, }, } for _, tt := range tests { diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index c072241..6be3bde 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -113,6 +113,10 @@ func CheckReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthrove return false, &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} } + if len(anthroveUserID) != 25 { + return false, &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} + } + result := db.WithContext(ctx).Model(&models.UserFavorites{}).Where("user_id = ? AND post_id = ?", string(anthroveUserID), string(anthrovePostID)).Count(&count) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { diff --git a/internal/postgres/relationships_test.go b/internal/postgres/relationships_test.go index e56b461..a758ad2 100644 --- a/internal/postgres/relationships_test.go +++ b/internal/postgres/relationships_test.go @@ -20,14 +20,20 @@ func TestCheckUserToPostLink(t *testing.T) { defer container.Terminate(ctx) // Setup Test - err = CreateUser(ctx, gormDB, "1") + + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + invalidUserID := models.AnthroveUserID("XXX") + + validPostID := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) + + err = CreateUser(ctx, gormDB, validUserID) if err != nil { t.Fatal(err) } post := &models.Post{ BaseModel: models.BaseModel[models.AnthrovePostID]{ - ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), + ID: validPostID, }, Rating: "safe", } @@ -37,7 +43,7 @@ func TestCheckUserToPostLink(t *testing.T) { t.Fatal(err) } - err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", models.AnthrovePostID(post.ID)) + err = CreateReferenceBetweenUserAndPost(ctx, gormDB, validUserID, post.ID) if err != nil { t.Fatal(err) } @@ -60,7 +66,7 @@ func TestCheckUserToPostLink(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validUserID, anthrovePostID: post.ID, }, want: true, @@ -71,33 +77,33 @@ func TestCheckUserToPostLink(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validUserID, anthrovePostID: "qadw", }, want: false, - wantErr: false, + wantErr: true, }, { name: "Test 3: Valid AnthrovePostID and invalid AnthroveUserID", args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "123", + anthroveUserID: invalidUserID, anthrovePostID: post.ID, }, want: false, - wantErr: false, + wantErr: true, }, { name: "Test 4: Invalid AnthrovePostID and invalid AnthroveUserID", args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "123", + anthroveUserID: invalidUserID, anthrovePostID: "123456", }, want: false, - wantErr: false, + wantErr: true, }, } for _, tt := range tests { @@ -219,14 +225,20 @@ func TestEstablishUserToPostLink(t *testing.T) { defer container.Terminate(ctx) // Setup Test - err = CreateUser(ctx, gormDB, "1") + + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + invalidUserID := models.AnthroveUserID("XXX") + + validPostID := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) + + err = CreateUser(ctx, gormDB, validUserID) if err != nil { t.Fatal(err) } post := &models.Post{ BaseModel: models.BaseModel[models.AnthrovePostID]{ - ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), + ID: validPostID, }, Rating: "safe", } @@ -253,7 +265,7 @@ func TestEstablishUserToPostLink(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validUserID, anthrovePostID: post.ID, }, wantErr: false, @@ -263,18 +275,18 @@ func TestEstablishUserToPostLink(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validUserID, anthrovePostID: "123456", }, wantErr: true, }, { - name: "Test 3: Valid AnthrovePostID and invalid AnthroveUserID", + name: "Test 3: invalid AnthroveUserID and valid AnthrovePostID", args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "123", - anthrovePostID: "1234", + anthroveUserID: invalidUserID, + anthrovePostID: post.ID, }, wantErr: true, }, @@ -283,7 +295,7 @@ func TestEstablishUserToPostLink(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "123", + anthroveUserID: invalidUserID, anthrovePostID: "123456", }, wantErr: true, diff --git a/internal/postgres/source_test.go b/internal/postgres/source_test.go index 80c0dc8..b618017 100644 --- a/internal/postgres/source_test.go +++ b/internal/postgres/source_test.go @@ -2,6 +2,7 @@ package postgres import ( "context" + "fmt" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/test" "gorm.io/gorm" @@ -19,7 +20,10 @@ func TestCreateSourceNode(t *testing.T) { // Setup Test + validPostID := models.AnthroveSourceID(fmt.Sprintf("%025s", "Post1")) + validSource := &models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: validPostID}, DisplayName: "e621", Domain: "e621.net", Icon: "icon.e621.net", @@ -65,7 +69,7 @@ func TestCreateSourceNode(t *testing.T) { db: gormDB, anthroveSource: validSource, }, - wantErr: false, + wantErr: true, }, } for _, tt := range tests { diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index 1983612..04c270a 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -21,6 +21,9 @@ func TestCreateUser(t *testing.T) { // Setup Test + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + invalidUserID := models.AnthroveUserID("XXX") + // Test type args struct { ctx context.Context @@ -37,7 +40,7 @@ func TestCreateUser(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validUserID, }, wantErr: false, }, @@ -46,7 +49,7 @@ func TestCreateUser(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "", + anthroveUserID: invalidUserID, }, wantErr: true, }, @@ -71,9 +74,14 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { // Setup Test + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + invalidUserID := models.AnthroveUserID("XXX") + + validSourceID := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source1")) + source := &models.Source{ BaseModel: models.BaseModel[models.AnthroveSourceID]{ - ID: models.AnthroveSourceID(fmt.Sprintf("%025s", "1")), + ID: validSourceID, }, DisplayName: "e621", Domain: "e621.net", @@ -103,7 +111,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validUserID, sourceID: source.ID, userID: "e1", username: "marius", @@ -115,7 +123,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "2", + anthroveUserID: invalidUserID, sourceID: source.ID, userID: "e1", username: "marius", @@ -139,7 +147,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validUserID, sourceID: "fa.net", userID: "e1", username: "marius", @@ -151,7 +159,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validUserID, sourceID: source.ID, userID: "", username: "marius", @@ -163,7 +171,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validUserID, sourceID: source.ID, userID: "aa", username: "", @@ -190,8 +198,11 @@ func TestGetAllAnthroveUserIDs(t *testing.T) { defer container.Terminate(ctx) // Setup Test + validUserID01 := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + validUserID02 := models.AnthroveUserID(fmt.Sprintf("%025s", "User2")) + validUserID03 := models.AnthroveUserID(fmt.Sprintf("%025s", "User3")) - users := []models.AnthroveUserID{"1", "2", "3"} + users := []models.AnthroveUserID{validUserID01, validUserID02, validUserID03} for _, user := range users { err = CreateUser(ctx, gormDB, user) @@ -246,6 +257,9 @@ func TestGetUserSourceBySourceID(t *testing.T) { // Setup Test + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + invalidUserID := models.AnthroveUserID("XXX") + expectedResult := make(map[string]models.UserSource) expectedResult["e621"] = models.UserSource{ UserID: "e1", @@ -269,7 +283,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { t.Fatal(err) } - err = CreateUserWithRelationToSource(ctx, gormDB, "1", models.AnthroveSourceID(expectedResult["e621"].SourceID), expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) + err = CreateUserWithRelationToSource(ctx, gormDB, validUserID, models.AnthroveSourceID(expectedResult["e621"].SourceID), expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) if err != nil { t.Fatal(err) } @@ -292,7 +306,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validUserID, sourceID: source.ID, }, want: expectedResult, @@ -303,7 +317,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "22", + anthroveUserID: invalidUserID, sourceID: source.ID, }, want: nil, @@ -314,7 +328,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validUserID, sourceID: "fa", }, want: nil, @@ -368,6 +382,8 @@ func TestGetUserSourceBySourceID(t *testing.T) { } } +// TODO: FIX THE FOUR REMAINING TESTS + func TestGetUserFavoriteNodeWithPagination(t *testing.T) { // Setup trow away containert ctx := context.Background() -- 2.45.1 From c550531a35b5c2449b820a507be8b0980cc67abb Mon Sep 17 00:00:00 2001 From: SoXX Date: Wed, 26 Jun 2024 09:10:04 +0200 Subject: [PATCH 093/124] tests(errors): refactored old tests to reflect new error handling Signed-off-by: SoXX --- internal/postgres/post.go | 5 +- internal/postgres/post_test.go | 5 +- internal/postgres/source.go | 3 +- internal/postgres/tag.go | 3 +- internal/postgres/user.go | 5 +- internal/postgres/user_test.go | 106 ++- pkg/database/postgres_test.go | 1229 +++++++++++++++++++++++++++++++- 7 files changed, 1281 insertions(+), 75 deletions(-) diff --git a/internal/postgres/post.go b/internal/postgres/post.go index 2206e00..edf7ac3 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -3,6 +3,7 @@ package postgres import ( "context" "errors" + errors2 "git.dragse.it/anthrove/otter-space-sdk/pkg/errors" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" @@ -42,7 +43,9 @@ func GetPostByAnthroveID(ctx context.Context, db *gorm.DB, anthrovePostID models return nil, &errors2.EntityValidationFailed{Reason: "anthrovePostID is not set"} } - //TODO maybe check ofor id length too...? + if len(anthrovePostID) != 25 { + return nil, &errors2.EntityValidationFailed{Reason: "anthrovePostID needs to be 25 characters long"} + } var post models.Post result := db.WithContext(ctx).First(&post, "id = ?", anthrovePostID) diff --git a/internal/postgres/post_test.go b/internal/postgres/post_test.go index 1b1bc83..99e5b32 100644 --- a/internal/postgres/post_test.go +++ b/internal/postgres/post_test.go @@ -3,11 +3,12 @@ package postgres import ( "context" "fmt" + "testing" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/test" _ "github.com/lib/pq" "gorm.io/gorm" - "testing" ) func TestCreateAnthrovePostNode(t *testing.T) { @@ -188,7 +189,7 @@ func TestGetPostBySourceURL(t *testing.T) { t.Fatal("Could not create source", err) } - err = CreateReferenceBetweenPostAndSource(ctx, gormDB, models.AnthrovePostID(post.ID), models.AnthroveSourceDomain(source.Domain)) + err = CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain)) if err != nil { t.Fatal("Could not create source reference", err) } diff --git a/internal/postgres/source.go b/internal/postgres/source.go index 1238a87..9321e42 100644 --- a/internal/postgres/source.go +++ b/internal/postgres/source.go @@ -3,6 +3,7 @@ package postgres import ( "context" "errors" + errors2 "git.dragse.it/anthrove/otter-space-sdk/pkg/errors" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" @@ -48,7 +49,7 @@ func GetAllSource(ctx context.Context, db *gorm.DB) ([]models.Source, error) { if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { return nil, &errors2.NoDataFound{} - } // TODO really...? i don't think this error handling should be here..? / not possible + } return nil, result.Error } diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 248a6a7..86f60d8 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -3,6 +3,7 @@ package postgres import ( "context" "errors" + errors2 "git.dragse.it/anthrove/otter-space-sdk/pkg/errors" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" log "github.com/sirupsen/logrus" @@ -78,7 +79,7 @@ func GetTags(ctx context.Context, db *gorm.DB) ([]models.Tag, error) { result := db.WithContext(ctx).Find(&tags) if result.Error != nil { - if errors.Is(result.Error, gorm.ErrRecordNotFound) { // TODO really...? i don't think this error handling should be here..? / not possible + if errors.Is(result.Error, gorm.ErrRecordNotFound) { return nil, &errors2.NoDataFound{} } return nil, result.Error diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 0e4070b..a21b266 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -3,6 +3,7 @@ package postgres import ( "context" "errors" + errors2 "git.dragse.it/anthrove/otter-space-sdk/pkg/errors" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" log "github.com/sirupsen/logrus" @@ -33,10 +34,6 @@ func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Anthrove return result.Error } - if result.RowsAffected == 0 { - return &errors2.NoDataWritten{} - } - return nil } diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index 04c270a..3c63d8c 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -3,11 +3,12 @@ package postgres import ( "context" "fmt" + "reflect" + "testing" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/test" "gorm.io/gorm" - "reflect" - "testing" ) func TestCreateUser(t *testing.T) { @@ -382,8 +383,6 @@ func TestGetUserSourceBySourceID(t *testing.T) { } } -// TODO: FIX THE FOUR REMAINING TESTS - func TestGetUserFavoriteNodeWithPagination(t *testing.T) { // Setup trow away containert ctx := context.Background() @@ -394,31 +393,39 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { defer container.Terminate(ctx) // Setup Test + validAnthroveUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + + validPostID1 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) + validPostID2 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post2")) + validPostID3 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post3")) + validPostID4 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post4")) + validPostID5 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post5")) + validPostID6 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post6")) expectedResultPosts := []models.Post{ { - BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post1"))}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID1}, Rating: "safe", }, { - BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post2"))}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID2}, Rating: "safe", }, { - BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post3"))}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID3}, Rating: "explicit", }, { - BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post4"))}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID4}, Rating: "explicit", }, { - BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post5"))}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID5}, Rating: "questionable", }, { - BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post6"))}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID6}, Rating: "safe", }, } @@ -432,7 +439,7 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { Posts: expectedResultPosts[:3], } - err = CreateUser(ctx, gormDB, "1") + err = CreateUser(ctx, gormDB, validAnthroveUserID) if err != nil { t.Fatal(err) } @@ -442,7 +449,7 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { if err != nil { t.Fatal(err) } - err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", models.AnthrovePostID(expectedResultPost.ID)) + err = CreateReferenceBetweenUserAndPost(ctx, gormDB, validAnthroveUserID, expectedResultPost.ID) if err != nil { t.Fatal(err) } @@ -467,7 +474,7 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validAnthroveUserID, skip: 0, limit: 2000, }, @@ -479,7 +486,7 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validAnthroveUserID, skip: 2, limit: 2000, }, @@ -491,7 +498,7 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validAnthroveUserID, skip: 0, limit: 3, }, @@ -524,44 +531,54 @@ func TestGetUserFavoritesCount(t *testing.T) { // Setup Test - err = CreateUser(ctx, gormDB, "1") - if err != nil { - t.Fatal(err) - } + validAnthroveUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + + validPostID1 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) + validPostID2 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post2")) + validPostID3 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post3")) + validPostID4 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post4")) + validPostID5 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post5")) + validPostID6 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post6")) expectedResultPosts := []models.Post{ { - BaseModel: models.BaseModel[models.AnthrovePostID]{ID: "Post1"}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID1}, Rating: "safe", }, { - BaseModel: models.BaseModel[models.AnthrovePostID]{ID: "Post2"}, + + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID2}, Rating: "safe", }, { - BaseModel: models.BaseModel[models.AnthrovePostID]{ID: "Post3"}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID3}, Rating: "explicit", }, { - BaseModel: models.BaseModel[models.AnthrovePostID]{ID: "Post4"}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID4}, Rating: "explicit", }, { - BaseModel: models.BaseModel[models.AnthrovePostID]{ID: "Post5"}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID5}, Rating: "questionable", }, { - BaseModel: models.BaseModel[models.AnthrovePostID]{ID: "Post6"}, + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID6}, Rating: "safe", }, } + err = CreateUser(ctx, gormDB, validAnthroveUserID) + if err != nil { + t.Fatal(err) + } + for _, post := range expectedResultPosts { err = CreatePost(ctx, gormDB, &post) if err != nil { t.Fatal(err) } - err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", models.AnthrovePostID(post.ID)) + err = CreateReferenceBetweenUserAndPost(ctx, gormDB, validAnthroveUserID, post.ID) if err != nil { t.Fatal(err) } @@ -584,7 +601,7 @@ func TestGetUserFavoritesCount(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validAnthroveUserID, }, want: 6, wantErr: false, @@ -597,7 +614,7 @@ func TestGetUserFavoritesCount(t *testing.T) { anthroveUserID: "2", }, want: 0, - wantErr: false, + wantErr: true, }, { name: "Test 3: no anthroveUserID and 6 favorite posts", @@ -634,8 +651,13 @@ func TestGetUserSourceLinks(t *testing.T) { defer container.Terminate(ctx) // Setup Test + validAnthroveUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + + validSourceID1 := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source1")) + validSourceID2 := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source2")) + eSource := &models.Source{ - BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: models.AnthroveSourceID(fmt.Sprintf("%025s", "1"))}, + BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: validSourceID1}, DisplayName: "e621", Domain: "e621.net", } @@ -645,7 +667,7 @@ func TestGetUserSourceLinks(t *testing.T) { } faSource := &models.Source{ - BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: models.AnthroveSourceID(fmt.Sprintf("%025s", "2"))}, + BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: validSourceID2}, DisplayName: "fa", Domain: "fa.net", } @@ -672,11 +694,11 @@ func TestGetUserSourceLinks(t *testing.T) { }, } - err = CreateUserWithRelationToSource(ctx, gormDB, "1", eSource.ID, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) + err = CreateUserWithRelationToSource(ctx, gormDB, validAnthroveUserID, eSource.ID, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) if err != nil { t.Fatal(err) } - err = CreateUserWithRelationToSource(ctx, gormDB, "1", faSource.ID, expectedResult["fa"].UserID, expectedResult["fa"].AccountUsername) + err = CreateUserWithRelationToSource(ctx, gormDB, validAnthroveUserID, faSource.ID, expectedResult["fa"].UserID, expectedResult["fa"].AccountUsername) if err != nil { t.Fatal(err) } @@ -698,7 +720,7 @@ func TestGetUserSourceLinks(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validAnthroveUserID, }, want: expectedResult, wantErr: false, @@ -728,15 +750,21 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { defer container.Terminate(ctx) // Setup Test - err = CreateUser(ctx, gormDB, "1") + validAnthroveUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + + validPostID1 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) + validPostID2 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post2")) + validPostID3 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post3")) + + err = CreateUser(ctx, gormDB, validAnthroveUserID) if err != nil { t.Fatal(err) } posts := []models.Post{ - {BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post1"))}, Rating: "safe"}, - {BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post2"))}, Rating: "safe"}, - {BaseModel: models.BaseModel[models.AnthrovePostID]{ID: models.AnthrovePostID(fmt.Sprintf("%-25s", "Post3"))}, Rating: "explicit"}, + {BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID1}, Rating: "safe"}, + {BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID2}, Rating: "safe"}, + {BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID3}, Rating: "explicit"}, } for _, post := range posts { @@ -744,7 +772,7 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { if err != nil { t.Fatal(err) } - err = CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", models.AnthrovePostID(post.ID)) + err = CreateReferenceBetweenUserAndPost(ctx, gormDB, validAnthroveUserID, models.AnthrovePostID(post.ID)) if err != nil { t.Fatal(err) } @@ -804,7 +832,7 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveUserID: "1", + anthroveUserID: validAnthroveUserID, }, want: expectedResult, wantErr: false, diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index f4cd28f..4103607 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -3,11 +3,13 @@ package database import ( "context" "fmt" + "reflect" "testing" "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/test" + "gorm.io/gorm" ) func TestNewPostgresqlConnection(t *testing.T) { @@ -95,9 +97,11 @@ func Test_postgresqlConnection_CreateUserWithRelationToSource(t *testing.T) { defer container.Terminate(ctx) // Setup Test + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + validSourceID1 := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source1")) source := &models.Source{ - BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: models.AnthroveSourceID(fmt.Sprintf("%025s", "1"))}, + BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: validSourceID1}, DisplayName: "e621", Domain: "e621.net", Icon: "icon.e621.net", @@ -124,7 +128,7 @@ func Test_postgresqlConnection_CreateUserWithRelationToSource(t *testing.T) { name: "Test 1: Valid anthroveUserID, sourceID, accountId, accountUsername", args: args{ ctx: ctx, - anthroveUserID: "1", + anthroveUserID: validUserID, sourceID: source.ID, accountId: "e1", accountUsername: "marius", @@ -157,7 +161,7 @@ func Test_postgresqlConnection_CreateUserWithRelationToSource(t *testing.T) { name: "Test 4: invalid sourceID", args: args{ ctx: ctx, - anthroveUserID: "1", + anthroveUserID: validUserID, sourceID: "fa.net", accountId: "e1", accountUsername: "marius", @@ -168,7 +172,7 @@ func Test_postgresqlConnection_CreateUserWithRelationToSource(t *testing.T) { name: "Test 5: no accountId", args: args{ ctx: ctx, - anthroveUserID: "1", + anthroveUserID: validUserID, sourceID: source.ID, accountId: "", accountUsername: "marius", @@ -179,7 +183,7 @@ func Test_postgresqlConnection_CreateUserWithRelationToSource(t *testing.T) { name: "Test 6: no accountUsername", args: args{ ctx: ctx, - anthroveUserID: "1", + anthroveUserID: validUserID, sourceID: source.ID, accountId: "aa", accountUsername: "", @@ -253,7 +257,7 @@ func Test_postgresqlConnection_CreateSource(t *testing.T) { ctx: ctx, anthroveSource: validSource, }, - wantErr: false, + wantErr: true, }, } for _, tt := range tests { @@ -280,9 +284,11 @@ func Test_postgresqlConnection_CreatePost(t *testing.T) { // Setup Tests + validPostID1 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) + validPost := &models.Post{ BaseModel: models.BaseModel[models.AnthrovePostID]{ - ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), + ID: validPostID1, }, Rating: "safe", } @@ -341,10 +347,11 @@ func Test_postgresqlConnection_CreateTagAndReferenceToPost(t *testing.T) { defer container.Terminate(ctx) // Setup Test + validPostID1 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) post := &models.Post{ BaseModel: models.BaseModel[models.AnthrovePostID]{ - ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), + ID: validPostID1, }, Rating: "safe", } @@ -430,23 +437,28 @@ func Test_postgresqlConnection_CreateReferenceBetweenPostAndSource(t *testing.T) defer container.Terminate(ctx) // Setup Test + validPostID1 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) + validSourceID1 := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source1")) + post := &models.Post{ BaseModel: models.BaseModel[models.AnthrovePostID]{ - ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), + ID: validPostID1, }, Rating: "safe", } + source := &models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: validSourceID1}, + DisplayName: "e621", + Domain: "e621.net", + Icon: "icon.e621.net", + } + err = postgres.CreatePost(ctx, gormDB, post) if err != nil { t.Fatal(err) } - source := &models.Source{ - DisplayName: "e621", - Domain: "e621.net", - Icon: "icon.e621.net", - } err = postgres.CreateSource(ctx, gormDB, source) if err != nil { t.Fatal(err) @@ -522,14 +534,17 @@ func Test_postgresqlConnection_CreateReferenceBetweenUserAndPost(t *testing.T) { defer container.Terminate(ctx) // Setup Test - err = postgres.CreateUser(ctx, gormDB, "1") + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + validPostID1 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) + + err = postgres.CreateUser(ctx, gormDB, validUserID) if err != nil { t.Fatal(err) } post := &models.Post{ BaseModel: models.BaseModel[models.AnthrovePostID]{ - ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), + ID: validPostID1, }, Rating: "safe", } @@ -554,7 +569,7 @@ func Test_postgresqlConnection_CreateReferenceBetweenUserAndPost(t *testing.T) { name: "Test 1: Valid AnthroveUserID and AnthrovePostID", args: args{ ctx: ctx, - anthroveUserID: "1", + anthroveUserID: validUserID, anthrovePostID: post.ID, }, wantErr: false, @@ -563,7 +578,7 @@ func Test_postgresqlConnection_CreateReferenceBetweenUserAndPost(t *testing.T) { name: "Test 2: Valid AnthroveUserID and invalid AnthrovePostID", args: args{ ctx: ctx, - anthroveUserID: "1", + anthroveUserID: validUserID, anthrovePostID: "123456", }, wantErr: true, @@ -610,14 +625,17 @@ func Test_postgresqlConnection_CheckReferenceBetweenUserAndPost(t *testing.T) { defer container.Terminate(ctx) // Setup Test - err = postgres.CreateUser(ctx, gormDB, "1") + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + validPostID1 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) + + err = postgres.CreateUser(ctx, gormDB, validUserID) if err != nil { t.Fatal(err) } post := &models.Post{ BaseModel: models.BaseModel[models.AnthrovePostID]{ - ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), + ID: validPostID1, }, Rating: "safe", } @@ -627,7 +645,7 @@ func Test_postgresqlConnection_CheckReferenceBetweenUserAndPost(t *testing.T) { t.Fatal(err) } - err = postgres.CreateReferenceBetweenUserAndPost(ctx, gormDB, "1", post.ID) + err = postgres.CreateReferenceBetweenUserAndPost(ctx, gormDB, validUserID, post.ID) if err != nil { t.Fatal(err) } @@ -648,7 +666,7 @@ func Test_postgresqlConnection_CheckReferenceBetweenUserAndPost(t *testing.T) { name: "Test 1: Valid AnthroveUserID and AnthrovePostID", args: args{ ctx: ctx, - anthroveUserID: "1", + anthroveUserID: validUserID, anthrovePostID: post.ID, }, want: true, @@ -658,11 +676,11 @@ func Test_postgresqlConnection_CheckReferenceBetweenUserAndPost(t *testing.T) { name: "Test 2: Valid AnthroveUserID and invalid AnthrovePostID", args: args{ ctx: ctx, - anthroveUserID: "1", + anthroveUserID: validUserID, anthrovePostID: "qadw", }, want: false, - wantErr: false, + wantErr: true, }, { name: "Test 3: Valid AnthrovePostID and invalid AnthroveUserID", @@ -672,7 +690,7 @@ func Test_postgresqlConnection_CheckReferenceBetweenUserAndPost(t *testing.T) { anthrovePostID: post.ID, }, want: false, - wantErr: false, + wantErr: true, }, { name: "Test 4: Invalid AnthrovePostID and invalid AnthroveUserID", @@ -682,7 +700,7 @@ func Test_postgresqlConnection_CheckReferenceBetweenUserAndPost(t *testing.T) { anthrovePostID: "123456", }, want: false, - wantErr: false, + wantErr: true, }, } for _, tt := range tests { @@ -713,10 +731,11 @@ func Test_postgresqlConnection_GetPostByAnthroveID(t *testing.T) { defer container.Terminate(ctx) // Setup Tests + validPostID1 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) post := &models.Post{ BaseModel: models.BaseModel[models.AnthrovePostID]{ - ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), + ID: validPostID1, }, Rating: "safe", } @@ -773,6 +792,1107 @@ func Test_postgresqlConnection_GetPostByAnthroveID(t *testing.T) { } } +func Test_postgresqlConnection_GetPostByURL(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Tests + validPostID1 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) + + post := &models.Post{ + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: validPostID1, + }, + Rating: "safe", + } + + err = postgres.CreatePost(ctx, gormDB, post) + if err != nil { + t.Fatal("Could not create post", err) + } + + source := models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ + ID: models.AnthroveSourceID(fmt.Sprintf("%025s", "1")), + }, + DisplayName: "e621", + Domain: "e621.net", + Icon: "https://e621.net/icon.ico", + } + + err = postgres.CreateSource(ctx, gormDB, &source) + if err != nil { + t.Fatal("Could not create source", err) + } + + err = postgres.CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain)) + if err != nil { + t.Fatal("Could not create source reference", err) + } + + // Test + type args struct { + ctx context.Context + sourceUrl string + } + tests := []struct { + name string + args args + want *models.Post + wantErr bool + }{ + { + name: "Test 1: Valid sourceUrl", + args: args{ + ctx: ctx, + sourceUrl: source.Domain, + }, + want: post, + wantErr: false, + }, + { + name: "Test 2: Invalid sourceUrl", + args: args{ + ctx: ctx, + sourceUrl: "1234", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 3: No sourceUrl", + args: args{ + ctx: ctx, + sourceUrl: "", + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetPostByURL(tt.args.ctx, tt.args.sourceUrl) + if (err != nil) != tt.wantErr { + t.Errorf("GetPostByURL() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !checkPost(got, tt.want) { + t.Errorf("GetPostByURL() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_postgresqlConnection_GetPostBySourceID(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Tests + validPostID1 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) + validSourceID1 := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source1")) + + post := &models.Post{ + BaseModel: models.BaseModel[models.AnthrovePostID]{ + ID: validPostID1, + }, + Rating: "safe", + } + + source := models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ + ID: validSourceID1, + }, + DisplayName: "e621", + Domain: "e621.net", + Icon: "https://e621.net/icon.ico", + } + + err = postgres.CreatePost(ctx, gormDB, post) + if err != nil { + t.Fatal("Could not create post", err) + } + + err = postgres.CreateSource(ctx, gormDB, &source) + if err != nil { + t.Fatal("Could not create source", err) + } + + err = postgres.CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain)) + if err != nil { + t.Fatal("Could not create source reference", err) + } + + // Test + type args struct { + ctx context.Context + sourceID models.AnthroveSourceID + } + tests := []struct { + name string + args args + want *models.Post + wantErr bool + }{ + { + name: "Test 1: Valid sourceID", + args: args{ + ctx: ctx, + sourceID: source.ID, + }, + want: post, + wantErr: false, + }, + { + name: "Test 2: Invalid sourceID", + args: args{ + ctx: ctx, + sourceID: "1234", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 3: No sourceID", + args: args{ + ctx: ctx, + sourceID: "", + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetPostBySourceID(tt.args.ctx, tt.args.sourceID) + if (err != nil) != tt.wantErr { + t.Errorf("GetPostBySourceID() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !checkPost(got, tt.want) { + t.Errorf("GetPostBySourceID() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_postgresqlConnection_GetUserFavoritesCount(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validAnthroveUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + + validPostID1 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) + validPostID2 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post2")) + validPostID3 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post3")) + validPostID4 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post4")) + validPostID5 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post5")) + validPostID6 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post6")) + + expectedResultPosts := []models.Post{ + { + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID1}, + Rating: "safe", + }, + { + + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID2}, + Rating: "safe", + }, + { + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID3}, + Rating: "explicit", + }, + { + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID4}, + Rating: "explicit", + }, + { + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID5}, + Rating: "questionable", + }, + { + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID6}, + Rating: "safe", + }, + } + + err = postgres.CreateUser(ctx, gormDB, validAnthroveUserID) + if err != nil { + t.Fatal(err) + } + + for _, post := range expectedResultPosts { + err = postgres.CreatePost(ctx, gormDB, &post) + if err != nil { + t.Fatal(err) + } + err = postgres.CreateReferenceBetweenUserAndPost(ctx, gormDB, validAnthroveUserID, post.ID) + if err != nil { + t.Fatal(err) + } + } + + // Test + type args struct { + ctx context.Context + anthroveUserID models.AnthroveUserID + } + tests := []struct { + name string + args args + want int64 + wantErr bool + }{ + { + name: "Test 1: Valid anthroveUserID and 6 favorite posts", + args: args{ + ctx: ctx, + anthroveUserID: validAnthroveUserID, + }, + want: 6, + wantErr: false, + }, + { + name: "Test 2: Invalid anthroveUserID and 6 favorite posts", + args: args{ + ctx: ctx, + anthroveUserID: "2", + }, + want: 0, + wantErr: true, + }, + { + name: "Test 3: no anthroveUserID and 6 favorite posts", + args: args{ + ctx: ctx, + anthroveUserID: "", + }, + want: 0, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetUserFavoritesCount(tt.args.ctx, tt.args.anthroveUserID) + if (err != nil) != tt.wantErr { + t.Errorf("GetUserFavoritesCount() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("GetUserFavoritesCount() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_postgresqlConnection_GetUserSourceLinks(t *testing.T) { + // Setup trow away containert + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validAnthroveUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + + validSourceID1 := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source1")) + validSourceID2 := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source2")) + + eSource := &models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: validSourceID1}, + DisplayName: "e621", + Domain: "e621.net", + } + err = postgres.CreateSource(ctx, gormDB, eSource) + if err != nil { + t.Fatal(err) + } + + faSource := &models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: validSourceID2}, + DisplayName: "fa", + Domain: "fa.net", + } + err = postgres.CreateSource(ctx, gormDB, faSource) + if err != nil { + t.Fatal(err) + } + + expectedResult := make(map[string]models.UserSource) + expectedResult["e621"] = models.UserSource{ + UserID: "e1", + AccountUsername: "e621-user", + Source: models.Source{ + DisplayName: eSource.DisplayName, + Domain: eSource.Domain, + }, + } + expectedResult["fa"] = models.UserSource{ + UserID: "fa1", + AccountUsername: "fa-user", + Source: models.Source{ + DisplayName: faSource.DisplayName, + Domain: faSource.Domain, + }, + } + + err = postgres.CreateUserWithRelationToSource(ctx, gormDB, validAnthroveUserID, eSource.ID, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) + if err != nil { + t.Fatal(err) + } + err = postgres.CreateUserWithRelationToSource(ctx, gormDB, validAnthroveUserID, faSource.ID, expectedResult["fa"].UserID, expectedResult["fa"].AccountUsername) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + anthroveUserID models.AnthroveUserID + } + tests := []struct { + name string + args args + want map[string]models.UserSource + wantErr bool + }{ + { + name: "Test 1: Get Data", + args: args{ + ctx: ctx, + anthroveUserID: validAnthroveUserID, + }, + want: expectedResult, + wantErr: false, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetUserSourceLinks(tt.args.ctx, tt.args.anthroveUserID) + if (err != nil) != tt.wantErr { + t.Errorf("GetUserSourceLinks() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetUserSourceLinks() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_postgresqlConnection_GetUserSourceBySourceID(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + invalidUserID := models.AnthroveUserID("XXX") + + expectedResult := make(map[string]models.UserSource) + expectedResult["e621"] = models.UserSource{ + UserID: "e1", + AccountUsername: "euser", + Source: models.Source{ + DisplayName: "e621", + Domain: "e621.net", + }, + } + + source := &models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ + ID: expectedResult["e621"].Source.ID, + }, + DisplayName: expectedResult["e621"].Source.DisplayName, + Domain: expectedResult["e621"].Source.Domain, + } + + err = postgres.CreateSource(ctx, gormDB, source) + if err != nil { + t.Fatal(err) + } + + err = postgres.CreateUserWithRelationToSource(ctx, gormDB, validUserID, models.AnthroveSourceID(expectedResult["e621"].SourceID), expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + anthroveUserID models.AnthroveUserID + sourceID models.AnthroveSourceID + } + tests := []struct { + name string + args args + want map[string]models.UserSource + wantErr bool + }{ + { + name: "Test 1: Valid AnthroveUserID and sourceID", + args: args{ + ctx: ctx, + anthroveUserID: validUserID, + sourceID: source.ID, + }, + want: expectedResult, + wantErr: false, + }, + { + name: "Test 2: Invalid AnthroveUserID and valid sourceID", + args: args{ + ctx: ctx, + anthroveUserID: invalidUserID, + sourceID: source.ID, + }, + want: nil, + wantErr: true, + }, + { + name: "Test 3: Valid AnthroveUserID and invalid sourceID", + args: args{ + ctx: ctx, + anthroveUserID: validUserID, + sourceID: "fa", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 4: No AnthroveUserID and Valid sourceID", + args: args{ + ctx: ctx, + anthroveUserID: "", + sourceID: source.ID, + }, + want: nil, + wantErr: true, + }, + { + name: "Test 5: Valid AnthroveUserID and No SourceDisplayName", + args: args{ + ctx: ctx, + anthroveUserID: "1", + sourceID: "", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 6: No AnthroveUserID and No SourceDisplayName", + args: args{ + ctx: ctx, + anthroveUserID: "", + sourceID: "", + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetUserSourceBySourceID(tt.args.ctx, tt.args.anthroveUserID, tt.args.sourceID) + if (err != nil) != tt.wantErr { + t.Errorf("GetUserSourceBySourceID() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetUserSourceBySourceID() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_postgresqlConnection_GetAllAnthroveUserIDs(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validUserID01 := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + validUserID02 := models.AnthroveUserID(fmt.Sprintf("%025s", "User2")) + validUserID03 := models.AnthroveUserID(fmt.Sprintf("%025s", "User3")) + + users := []models.AnthroveUserID{validUserID01, validUserID02, validUserID03} + + for _, user := range users { + err = postgres.CreateUser(ctx, gormDB, user) + if err != nil { + t.Fatal(err) + } + } + + // Test + type args struct { + ctx context.Context + } + tests := []struct { + name string + args args + want []models.AnthroveUserID + wantErr bool + }{ + { + name: "Test 1: Get Data", + args: args{ + ctx: ctx, + }, + want: users, + wantErr: false, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetAllAnthroveUserIDs(tt.args.ctx) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllAnthroveUserIDs() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetAllAnthroveUserIDs() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_postgresqlConnection_GetUserFavoriteWithPagination(t *testing.T) { + // Setup trow away containert + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validAnthroveUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + + validPostID1 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) + validPostID2 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post2")) + validPostID3 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post3")) + validPostID4 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post4")) + validPostID5 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post5")) + validPostID6 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post6")) + + expectedResultPosts := []models.Post{ + { + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID1}, + Rating: "safe", + }, + { + + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID2}, + Rating: "safe", + }, + { + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID3}, + Rating: "explicit", + }, + { + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID4}, + Rating: "explicit", + }, + { + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID5}, + Rating: "questionable", + }, + { + BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID6}, + Rating: "safe", + }, + } + expectedResult := &models.FavoriteList{ + Posts: expectedResultPosts, + } + expectedResult2 := &models.FavoriteList{ + Posts: expectedResultPosts[2:], + } + expectedResult3 := &models.FavoriteList{ + Posts: expectedResultPosts[:3], + } + + err = postgres.CreateUser(ctx, gormDB, validAnthroveUserID) + if err != nil { + t.Fatal(err) + } + + for _, expectedResultPost := range expectedResultPosts { + err = postgres.CreatePost(ctx, gormDB, &expectedResultPost) + if err != nil { + t.Fatal(err) + } + err = postgres.CreateReferenceBetweenUserAndPost(ctx, gormDB, validAnthroveUserID, expectedResultPost.ID) + if err != nil { + t.Fatal(err) + } + } + + // Test + type args struct { + ctx context.Context + anthroveUserID models.AnthroveUserID + skip int + limit int + } + tests := []struct { + name string + args args + want *models.FavoriteList + wantErr bool + }{ + { + name: "Test 1: Valid AnthroveUserID", + args: args{ + ctx: ctx, + anthroveUserID: validAnthroveUserID, + skip: 0, + limit: 2000, + }, + want: expectedResult, + wantErr: false, + }, + { + name: "Test 2: Skip first two", + args: args{ + ctx: ctx, + anthroveUserID: validAnthroveUserID, + skip: 2, + limit: 2000, + }, + want: expectedResult2, + wantErr: false, + }, + { + name: "Test 3: Limit of 3", + args: args{ + ctx: ctx, + anthroveUserID: validAnthroveUserID, + skip: 0, + limit: 3, + }, + want: expectedResult3, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetUserFavoriteWithPagination(tt.args.ctx, tt.args.anthroveUserID, tt.args.skip, tt.args.limit) + if (err != nil) != tt.wantErr { + t.Errorf("GetUserFavoriteWithPagination() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetUserFavoriteWithPagination() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_postgresqlConnection_GetUserTagWitRelationToFavedPosts(t *testing.T) { + // Setup trow away containert + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validAnthroveUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + + validPostID1 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) + validPostID2 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post2")) + validPostID3 := models.AnthrovePostID(fmt.Sprintf("%025s", "Post3")) + + err = postgres.CreateUser(ctx, gormDB, validAnthroveUserID) + if err != nil { + t.Fatal(err) + } + + posts := []models.Post{ + {BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID1}, Rating: "safe"}, + {BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID2}, Rating: "safe"}, + {BaseModel: models.BaseModel[models.AnthrovePostID]{ID: validPostID3}, Rating: "explicit"}, + } + + for _, post := range posts { + err = postgres.CreatePost(ctx, gormDB, &post) + if err != nil { + t.Fatal(err) + } + err = postgres.CreateReferenceBetweenUserAndPost(ctx, gormDB, validAnthroveUserID, models.AnthrovePostID(post.ID)) + if err != nil { + t.Fatal(err) + } + } + + tags := []models.Tag{ + {Name: "JayTheFerret", Type: "artist"}, + {Name: "Ferret", Type: "species"}, + {Name: "Jay", Type: "character"}, + } + + for i, tag := range tags { + err = postgres.CreateTagAndReferenceToPost(ctx, gormDB, posts[i].ID, &tag) + if err != nil { + t.Fatal(err) + } + } + + expectedResult := []models.TagsWithFrequency{ + { + Frequency: 1, + Tags: models.Tag{ + Name: tags[0].Name, + Type: tags[0].Type, + }, + }, + { + Frequency: 1, + Tags: models.Tag{ + Name: tags[1].Name, + Type: tags[1].Type, + }, + }, + { + Frequency: 1, + Tags: models.Tag{ + Name: tags[2].Name, + Type: tags[2].Type, + }, + }, + } + + // Test + type args struct { + ctx context.Context + anthroveUserID models.AnthroveUserID + } + tests := []struct { + name string + args args + want []models.TagsWithFrequency + wantErr bool + }{ + { + name: "Test 1: Get Data", + args: args{ + ctx: ctx, + anthroveUserID: validAnthroveUserID, + }, + want: expectedResult, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetUserTagWitRelationToFavedPosts(tt.args.ctx, tt.args.anthroveUserID) + if (err != nil) != tt.wantErr { + t.Errorf("GetUserTagWitRelationToFavedPosts() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetUserTagWitRelationToFavedPosts() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_postgresqlConnection_GetAllTags(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + tags := []models.Tag{ + { + Name: "JayTheFerret", + Type: "artist", + }, + { + Name: "anthro", + Type: "general", + }, + { + Name: "soxx", + Type: "character", + }, + } + + for _, tag := range tags { + err = postgres.CreateTag(ctx, gormDB, &tag) + if err != nil { + t.Fatal(err) + } + } + + // Test + type args struct { + ctx context.Context + } + tests := []struct { + name string + args args + want []models.Tag + wantErr bool + }{ + { + name: "Test 1: Get Tags", + args: args{ + ctx: ctx, + }, + want: tags, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetAllTags(tt.args.ctx) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllTags() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetAllTags() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_postgresqlConnection_GetAllSources(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + sources := []models.Source{ + { + DisplayName: "e621", + Domain: "e621.net", + Icon: "icon.e621.net", + }, + { + DisplayName: "furaffinity", + Domain: "furaffinity.net", + Icon: "icon.furaffinity.net", + }, + { + DisplayName: "fenpaws", + Domain: "fenpa.ws", + Icon: "icon.fenpa.ws", + }, + } + + for _, source := range sources { + err = postgres.CreateSource(ctx, gormDB, &source) + if err != nil { + t.Fatal(err) + } + } + + // Test + type args struct { + ctx context.Context + } + tests := []struct { + name string + args args + want []models.Source + wantErr bool + }{ + { + name: "Test 1: Get all entries", + args: args{ + ctx: ctx, + }, + want: sources, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetAllSources(tt.args.ctx) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllSources() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !checkSources(got, tt.want) { + t.Errorf("GetAllSources() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_postgresqlConnection_GetSourceByDomain(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + source := &models.Source{ + DisplayName: "e621", + Domain: "e621.net", + Icon: "icon.e621.net", + } + + err = postgres.CreateSource(ctx, gormDB, source) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + sourceDomain models.AnthroveSourceDomain + } + tests := []struct { + name string + args args + want *models.Source + wantErr bool + }{ + { + name: "Test 1: Valid URL", + args: args{ + ctx: ctx, + sourceDomain: "e621.net", + }, + want: source, + wantErr: false, + }, + { + name: "Test 2: Invalid URL", + args: args{ + ctx: ctx, + sourceDomain: "eeeee.net", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 2: No URL", + args: args{ + ctx: ctx, + sourceDomain: "", + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetSourceByDomain(tt.args.ctx, tt.args.sourceDomain) + if (err != nil) != tt.wantErr { + t.Errorf("GetSourceByDomain() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !checkSource(got, tt.want) { + t.Errorf("GetSourceByDomain() got = %v, want %v", got, tt.want) + } + }) + } +} + +func checkSource(got *models.Source, want *models.Source) bool { + + if want == nil && got == nil { + return true + } + + if got.Domain != want.Domain { + return false + } + + return true + +} + func checkPost(got *models.Post, want *models.Post) bool { if got == nil && want == nil { @@ -791,3 +1911,58 @@ func checkPost(got *models.Post, want *models.Post) bool { return true } + +func checkSources(got []models.Source, want []models.Source) bool { + for i, source := range want { + if source.DisplayName != got[i].DisplayName { + return false + } + if source.Domain != got[i].Domain { + return false + } + if source.Icon != got[i].Icon { + return false + } + } + + return true +} + +func Test_postgresqlConnection_migrateDatabase(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + // Test + type args struct { + dbPool *gorm.DB + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Migrate Databases", + args: args{dbPool: gormDB}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.migrateDatabase(tt.args.dbPool); (err != nil) != tt.wantErr { + t.Errorf("migrateDatabase() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} -- 2.45.1 From 4fa936d774bc773d12e8cb36e4216cf6d1194517 Mon Sep 17 00:00:00 2001 From: SoXX Date: Wed, 26 Jun 2024 09:20:52 +0200 Subject: [PATCH 094/124] fix(errors): added const Signed-off-by: SoXX --- internal/postgres/relationships.go | 13 +++++++------ internal/postgres/user.go | 28 ++++++++++++++-------------- pkg/errors/validation.go | 5 +++++ 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index 6be3bde..d66106b 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -3,6 +3,7 @@ package postgres import ( "context" "errors" + errors2 "git.dragse.it/anthrove/otter-space-sdk/pkg/errors" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" log "github.com/sirupsen/logrus" @@ -13,11 +14,11 @@ func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthr var source models.Source if anthrovePostID == "" { - return &errors2.EntityValidationFailed{Reason: "anthrovePostID cannot be empty"} + return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} } if len(anthrovePostID) != 25 { - return &errors2.EntityValidationFailed{Reason: "anthrovePostID needs to be 25 characters long"} + return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} } if sourceDomain == "" { @@ -62,11 +63,11 @@ func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthr func CreateReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error { if anthrovePostID == "" { - return &errors2.EntityValidationFailed{Reason: "anthrovePostID cannot be empty"} + return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} } if len(anthrovePostID) != 25 { - return &errors2.EntityValidationFailed{Reason: "anthrovePostID needs to be 25 characters long"} + return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} } if anthroveUserID == "" { @@ -102,11 +103,11 @@ func CheckReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthrove var count int64 if anthrovePostID == "" { - return false, &errors2.EntityValidationFailed{Reason: "anthrovePostID cannot be empty"} + return false, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} } if len(anthrovePostID) != 25 { - return false, &errors2.EntityValidationFailed{Reason: "anthrovePostID needs to be 25 characters long"} + return false, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} } if anthroveUserID == "" { diff --git a/internal/postgres/user.go b/internal/postgres/user.go index a21b266..55a1d54 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -13,11 +13,11 @@ import ( func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) error { if anthroveUserID == "" { - return &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} } if len(anthroveUserID) != 25 { - return &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} + return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} } user := models.User{ @@ -40,11 +40,11 @@ func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Anthrove func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, accountId string, accountUsername string) error { if anthroveUserID == "" { - return &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} } if len(anthroveUserID) != 25 { - return &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} + return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} } if accountId == "" { @@ -103,11 +103,11 @@ func GetUserFavoritesCount(ctx context.Context, db *gorm.DB, anthroveUserID mode var count int64 if anthroveUserID == "" { - return 0, &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + return 0, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} } if len(anthroveUserID) != 25 { - return 0, &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} + return 0, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} } result := db.WithContext(ctx).Model(&models.UserFavorites{}).Where("user_id = ?", string(anthroveUserID)).Count(&count) @@ -131,11 +131,11 @@ func GetUserSourceLinks(ctx context.Context, db *gorm.DB, anthroveUserID models. userSourceMap := make(map[string]models.UserSource) if anthroveUserID == "" { - return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} } if len(anthroveUserID) != 25 { - return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} + return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} } result := db.WithContext(ctx).Model(&models.UserSource{}).Where("user_id = ?", string(anthroveUserID)).Find(&userSources) @@ -179,11 +179,11 @@ func GetUserSourceBySourceID(ctx context.Context, db *gorm.DB, anthroveUserID mo userSourceMap := make(map[string]models.UserSource) if anthroveUserID == "" { - return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} } if len(anthroveUserID) != 25 { - return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} + return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} } if sourceID == "" { @@ -259,11 +259,11 @@ func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUse var favoritePosts []models.Post if anthroveUserID == "" { - return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} } if len(anthroveUserID) != 25 { - return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} + return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} } err := db.WithContext(ctx).Model(&models.UserFavorites{}).Where("user_id = ?", string(anthroveUserID)).Offset(skip).Limit(limit).Find(&userFavorites).Error @@ -303,11 +303,11 @@ func GetUserTagWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthrov var userFavorites []models.UserFavorites if anthroveUserID == "" { - return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} } if len(anthroveUserID) != 25 { - return nil, &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} + return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} } result := db.WithContext(ctx).Where("user_id = ?", string(anthroveUserID)).Find(&userFavorites) diff --git a/pkg/errors/validation.go b/pkg/errors/validation.go index a04ac75..69efe47 100644 --- a/pkg/errors/validation.go +++ b/pkg/errors/validation.go @@ -2,6 +2,11 @@ package errors import "fmt" +const ( + AnthroveUserIDIsEmpty = "anthrovePostID cannot be empty" + AnthroveUserIDToShort = "anthrovePostID needs to be 25 characters long" +) + type EntityValidationFailed struct { Reason string } -- 2.45.1 From 6e3edfc1fa110cc1b77f610f457948b245117665 Mon Sep 17 00:00:00 2001 From: SoXX Date: Wed, 26 Jun 2024 10:02:54 +0200 Subject: [PATCH 095/124] fix(errors): renamed error package Signed-off-by: SoXX --- internal/postgres/post.go | 22 +++++----- internal/postgres/relationships.go | 34 +++++++-------- internal/postgres/source.go | 14 +++--- internal/postgres/tag.go | 20 ++++----- internal/postgres/user.go | 66 ++++++++++++++--------------- pkg/{errors => error}/database.go | 2 +- pkg/{errors => error}/validation.go | 2 +- 7 files changed, 80 insertions(+), 80 deletions(-) rename pkg/{errors => error}/database.go (96%) rename pkg/{errors => error}/validation.go (95%) diff --git a/internal/postgres/post.go b/internal/postgres/post.go index edf7ac3..3679132 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -4,7 +4,7 @@ import ( "context" "errors" - errors2 "git.dragse.it/anthrove/otter-space-sdk/pkg/errors" + otterError "git.dragse.it/anthrove/otter-space-sdk/pkg/error" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" log "github.com/sirupsen/logrus" @@ -14,19 +14,19 @@ import ( func CreatePost(ctx context.Context, db *gorm.DB, anthrovePost *models.Post) error { if anthrovePost == nil { - return &errors2.EntityValidationFailed{Reason: "anthrovePost is nil"} + return &otterError.EntityValidationFailed{Reason: "anthrovePost is nil"} } result := db.WithContext(ctx).Create(&anthrovePost) if result.Error != nil { if errors.Is(result.Error, gorm.ErrDuplicatedKey) { - return &errors2.EntityAlreadyExists{} + return &otterError.EntityAlreadyExists{} } return result.Error } if result.RowsAffected == 0 { - return &errors2.NoDataWritten{} + return &otterError.NoDataWritten{} } log.WithFields(log.Fields{ @@ -40,18 +40,18 @@ func CreatePost(ctx context.Context, db *gorm.DB, anthrovePost *models.Post) err func GetPostByAnthroveID(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID) (*models.Post, error) { if anthrovePostID == "" { - return nil, &errors2.EntityValidationFailed{Reason: "anthrovePostID is not set"} + return nil, &otterError.EntityValidationFailed{Reason: "anthrovePostID is not set"} } if len(anthrovePostID) != 25 { - return nil, &errors2.EntityValidationFailed{Reason: "anthrovePostID needs to be 25 characters long"} + return nil, &otterError.EntityValidationFailed{Reason: "anthrovePostID needs to be 25 characters long"} } var post models.Post result := db.WithContext(ctx).First(&post, "id = ?", anthrovePostID) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &errors2.NoDataFound{} + return nil, &otterError.NoDataFound{} } return nil, result.Error } @@ -62,7 +62,7 @@ func GetPostByAnthroveID(ctx context.Context, db *gorm.DB, anthrovePostID models func GetPostByURL(ctx context.Context, db *gorm.DB, sourceURL string) (*models.Post, error) { if sourceURL == "" { - return nil, &errors2.EntityValidationFailed{Reason: "sourceURL is not set"} + return nil, &otterError.EntityValidationFailed{Reason: "sourceURL is not set"} } var post models.Post @@ -70,7 +70,7 @@ func GetPostByURL(ctx context.Context, db *gorm.DB, sourceURL string) (*models.P if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &errors2.NoDataFound{} + return nil, &otterError.NoDataFound{} } return nil, result.Error } @@ -81,7 +81,7 @@ func GetPostByURL(ctx context.Context, db *gorm.DB, sourceURL string) (*models.P func GetPostBySourceID(ctx context.Context, db *gorm.DB, sourceID models.AnthroveSourceID) (*models.Post, error) { if sourceID == "" { - return nil, &errors2.EntityValidationFailed{Reason: "sourceID is not set"} + return nil, &otterError.EntityValidationFailed{Reason: "sourceID is not set"} } var post models.Post @@ -89,7 +89,7 @@ func GetPostBySourceID(ctx context.Context, db *gorm.DB, sourceID models.Anthrov if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &errors2.NoDataFound{} + return nil, &otterError.NoDataFound{} } return nil, result.Error } diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index d66106b..8aa1079 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -4,7 +4,7 @@ import ( "context" "errors" - errors2 "git.dragse.it/anthrove/otter-space-sdk/pkg/errors" + otterError "git.dragse.it/anthrove/otter-space-sdk/pkg/error" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" log "github.com/sirupsen/logrus" "gorm.io/gorm" @@ -14,22 +14,22 @@ func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthr var source models.Source if anthrovePostID == "" { - return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} } if len(anthrovePostID) != 25 { - return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort} } if sourceDomain == "" { - return &errors2.EntityValidationFailed{Reason: "sourceDomain cannot be empty"} + return &otterError.EntityValidationFailed{Reason: "sourceDomain cannot be empty"} } // Find the source result := db.WithContext(ctx).Where("domain = ?", sourceDomain).First(&source) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return &errors2.NoDataFound{} + return &otterError.NoDataFound{} } return result.Error } @@ -43,13 +43,13 @@ func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthr if result.Error != nil { if errors.Is(result.Error, gorm.ErrDuplicatedKey) { - return &errors2.EntityAlreadyExists{} + return &otterError.EntityAlreadyExists{} } return result.Error } if result.RowsAffected == 0 { - return &errors2.NoDataWritten{} + return &otterError.NoDataWritten{} } log.WithFields(log.Fields{ @@ -63,15 +63,15 @@ func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthr func CreateReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error { if anthrovePostID == "" { - return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} } if len(anthrovePostID) != 25 { - return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort} } if anthroveUserID == "" { - return &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + return &otterError.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} } userFavorite := models.UserFavorites{ @@ -82,13 +82,13 @@ func CreateReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthrov result := db.WithContext(ctx).Create(&userFavorite) if result.Error != nil { if errors.Is(result.Error, gorm.ErrDuplicatedKey) { - return &errors2.EntityAlreadyExists{} + return &otterError.EntityAlreadyExists{} } return result.Error } if result.RowsAffected == 0 { - return &errors2.NoDataWritten{} + return &otterError.NoDataWritten{} } log.WithFields(log.Fields{ @@ -103,25 +103,25 @@ func CheckReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthrove var count int64 if anthrovePostID == "" { - return false, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} + return false, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} } if len(anthrovePostID) != 25 { - return false, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} + return false, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort} } if anthroveUserID == "" { - return false, &errors2.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} + return false, &otterError.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"} } if len(anthroveUserID) != 25 { - return false, &errors2.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} + return false, &otterError.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"} } result := db.WithContext(ctx).Model(&models.UserFavorites{}).Where("user_id = ? AND post_id = ?", string(anthroveUserID), string(anthrovePostID)).Count(&count) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return false, &errors2.NoDataFound{} + return false, &otterError.NoDataFound{} } return false, result.Error } diff --git a/internal/postgres/source.go b/internal/postgres/source.go index 9321e42..bdb2122 100644 --- a/internal/postgres/source.go +++ b/internal/postgres/source.go @@ -4,7 +4,7 @@ import ( "context" "errors" - errors2 "git.dragse.it/anthrove/otter-space-sdk/pkg/errors" + otterError "git.dragse.it/anthrove/otter-space-sdk/pkg/error" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" log "github.com/sirupsen/logrus" @@ -15,20 +15,20 @@ import ( func CreateSource(ctx context.Context, db *gorm.DB, anthroveSource *models.Source) error { if anthroveSource.Domain == "" { - return &errors2.EntityValidationFailed{Reason: "Domain is required"} + return &otterError.EntityValidationFailed{Reason: "Domain is required"} } result := db.WithContext(ctx).Where(models.Source{Domain: anthroveSource.Domain}).FirstOrCreate(anthroveSource) if result.Error != nil { if errors.Is(result.Error, gorm.ErrDuplicatedKey) { - return &errors2.EntityAlreadyExists{} + return &otterError.EntityAlreadyExists{} } return result.Error } if result.RowsAffected == 0 { - return &errors2.NoDataWritten{} + return &otterError.NoDataWritten{} } log.WithFields(log.Fields{ @@ -48,7 +48,7 @@ func GetAllSource(ctx context.Context, db *gorm.DB) ([]models.Source, error) { if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &errors2.NoDataFound{} + return nil, &otterError.NoDataFound{} } return nil, result.Error } @@ -65,14 +65,14 @@ func GetSourceByDomain(ctx context.Context, db *gorm.DB, sourceDomain models.Ant var sources models.Source if sourceDomain == "" { - return nil, &errors2.EntityValidationFailed{Reason: "AnthroveSourceDomain is not set"} + return nil, &otterError.EntityValidationFailed{Reason: "AnthroveSourceDomain is not set"} } result := db.WithContext(ctx).Where("domain = ?", sourceDomain).First(&sources) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &errors2.NoDataFound{} + return nil, &otterError.NoDataFound{} } return nil, result.Error } diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 86f60d8..93b5467 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -4,7 +4,7 @@ import ( "context" "errors" - errors2 "git.dragse.it/anthrove/otter-space-sdk/pkg/errors" + otterError "git.dragse.it/anthrove/otter-space-sdk/pkg/error" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" log "github.com/sirupsen/logrus" "gorm.io/gorm" @@ -13,19 +13,19 @@ import ( func CreateTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { if tag == nil { - return &errors2.EntityValidationFailed{Reason: "Tag is nil"} + return &otterError.EntityValidationFailed{Reason: "Tag is nil"} } result := db.WithContext(ctx).Where(tag).Create(tag) if result.Error != nil { if errors.Is(result.Error, gorm.ErrDuplicatedKey) { - return &errors2.EntityAlreadyExists{} + return &otterError.EntityAlreadyExists{} } return result.Error } if result.RowsAffected == 0 { - return &errors2.NoDataWritten{} + return &otterError.NoDataWritten{} } log.WithFields(log.Fields{ @@ -39,15 +39,15 @@ func CreateTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { func CreateTagAndReferenceToPost(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, tag *models.Tag) error { if anthrovePostID == "" { - return &errors2.EntityValidationFailed{Reason: "anthrovePostID cannot be empty"} + return &otterError.EntityValidationFailed{Reason: "anthrovePostID cannot be empty"} } if len(anthrovePostID) != 25 { - return &errors2.EntityValidationFailed{Reason: "anthrovePostID needs to be 25 characters long"} + return &otterError.EntityValidationFailed{Reason: "anthrovePostID needs to be 25 characters long"} } if tag == nil { - return &errors2.EntityValidationFailed{Reason: "Tag is nil"} + return &otterError.EntityValidationFailed{Reason: "Tag is nil"} } pgPost := models.Post{ @@ -59,9 +59,9 @@ func CreateTagAndReferenceToPost(ctx context.Context, db *gorm.DB, anthrovePostI err := db.WithContext(ctx).Model(&pgPost).Association("Tags").Append(tag) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return &errors2.NoDataFound{} + return &otterError.NoDataFound{} } - return errors.Join(err, &errors2.NoRelationCreated{}) + return errors.Join(err, &otterError.NoRelationCreated{}) } log.WithFields(log.Fields{ @@ -80,7 +80,7 @@ func GetTags(ctx context.Context, db *gorm.DB) ([]models.Tag, error) { if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &errors2.NoDataFound{} + return nil, &otterError.NoDataFound{} } return nil, result.Error } diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 55a1d54..499911b 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -4,7 +4,7 @@ import ( "context" "errors" - errors2 "git.dragse.it/anthrove/otter-space-sdk/pkg/errors" + otterError "git.dragse.it/anthrove/otter-space-sdk/pkg/error" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" log "github.com/sirupsen/logrus" "gorm.io/gorm" @@ -13,11 +13,11 @@ import ( func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) error { if anthroveUserID == "" { - return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} } if len(anthroveUserID) != 25 { - return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort} } user := models.User{ @@ -29,7 +29,7 @@ func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Anthrove result := db.WithContext(ctx).FirstOrCreate(&user) if result.Error != nil { if errors.Is(result.Error, gorm.ErrDuplicatedKey) { - return &errors2.EntityAlreadyExists{} + return &otterError.EntityAlreadyExists{} } return result.Error } @@ -40,19 +40,19 @@ func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Anthrove func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, accountId string, accountUsername string) error { if anthroveUserID == "" { - return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} } if len(anthroveUserID) != 25 { - return &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort} } if accountId == "" { - return &errors2.EntityValidationFailed{Reason: "accountID cannot be empty"} + return &otterError.EntityValidationFailed{Reason: "accountID cannot be empty"} } if accountUsername == "" { - return &errors2.EntityValidationFailed{Reason: "accountUsername cannot be empty"} + return &otterError.EntityValidationFailed{Reason: "accountUsername cannot be empty"} } err := CreateUser(ctx, db, anthroveUserID) @@ -67,7 +67,7 @@ func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUs result := db.WithContext(ctx).Where(&source).First(&source) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return &errors2.NoDataFound{} + return &otterError.NoDataFound{} } return result.Error } @@ -82,11 +82,11 @@ func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUs result = db.WithContext(ctx).FirstOrCreate(&userSource) if result.Error != nil { - return errors.Join(result.Error, &errors2.NoRelationCreated{}) + return errors.Join(result.Error, &otterError.NoRelationCreated{}) } if result.RowsAffected == 0 { - return &errors2.NoDataWritten{} + return &otterError.NoDataWritten{} } log.WithFields(log.Fields{ @@ -103,17 +103,17 @@ func GetUserFavoritesCount(ctx context.Context, db *gorm.DB, anthroveUserID mode var count int64 if anthroveUserID == "" { - return 0, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} + return 0, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} } if len(anthroveUserID) != 25 { - return 0, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} + return 0, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort} } result := db.WithContext(ctx).Model(&models.UserFavorites{}).Where("user_id = ?", string(anthroveUserID)).Count(&count) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return 0, &errors2.NoDataFound{} + return 0, &otterError.NoDataFound{} } return 0, result.Error } @@ -131,17 +131,17 @@ func GetUserSourceLinks(ctx context.Context, db *gorm.DB, anthroveUserID models. userSourceMap := make(map[string]models.UserSource) if anthroveUserID == "" { - return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} + return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} } if len(anthroveUserID) != 25 { - return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} + return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort} } result := db.WithContext(ctx).Model(&models.UserSource{}).Where("user_id = ?", string(anthroveUserID)).Find(&userSources) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &errors2.NoDataFound{} + return nil, &otterError.NoDataFound{} } return nil, result.Error } @@ -151,7 +151,7 @@ func GetUserSourceLinks(ctx context.Context, db *gorm.DB, anthroveUserID models. result = db.WithContext(ctx).Model(&models.Source{}).Where("id = ?", userSource.SourceID).First(&source) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &errors2.NoDataFound{} + return nil, &otterError.NoDataFound{} } return nil, result.Error } @@ -179,25 +179,25 @@ func GetUserSourceBySourceID(ctx context.Context, db *gorm.DB, anthroveUserID mo userSourceMap := make(map[string]models.UserSource) if anthroveUserID == "" { - return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} + return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} } if len(anthroveUserID) != 25 { - return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} + return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort} } if sourceID == "" { - return nil, &errors2.EntityValidationFailed{Reason: "sourceID cannot be empty"} + return nil, &otterError.EntityValidationFailed{Reason: "sourceID cannot be empty"} } if len(sourceID) != 25 { - return nil, &errors2.EntityValidationFailed{Reason: "sourceID needs to be 25 characters long"} + return nil, &otterError.EntityValidationFailed{Reason: "sourceID needs to be 25 characters long"} } result := db.WithContext(ctx).Model(&models.UserSource{}).InnerJoins("Source", db.Where("id = ?", sourceID)).Where("user_id = ?", string(anthroveUserID)).First(&userSources) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &errors2.NoDataFound{} + return nil, &otterError.NoDataFound{} } return nil, result.Error } @@ -207,7 +207,7 @@ func GetUserSourceBySourceID(ctx context.Context, db *gorm.DB, anthroveUserID mo result = db.WithContext(ctx).Model(&models.Source{}).Where("id = ?", userSource.SourceID).First(&source) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &errors2.NoDataFound{} + return nil, &otterError.NoDataFound{} } return nil, result.Error } @@ -238,7 +238,7 @@ func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveU result := db.WithContext(ctx).Model(&models.User{}).Find(&users) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &errors2.NoDataFound{} + return nil, &otterError.NoDataFound{} } return nil, result.Error } @@ -259,17 +259,17 @@ func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUse var favoritePosts []models.Post if anthroveUserID == "" { - return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} + return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} } if len(anthroveUserID) != 25 { - return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} + return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort} } err := db.WithContext(ctx).Model(&models.UserFavorites{}).Where("user_id = ?", string(anthroveUserID)).Offset(skip).Limit(limit).Find(&userFavorites).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return nil, &errors2.NoDataFound{} + return nil, &otterError.NoDataFound{} } return nil, err } @@ -279,7 +279,7 @@ func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUse err = db.WithContext(ctx).Model(&models.Post{}).Where("id = ?", userFavorite.PostID).First(&post).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return nil, &errors2.NoDataFound{} + return nil, &otterError.NoDataFound{} } return nil, err } @@ -303,17 +303,17 @@ func GetUserTagWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthrov var userFavorites []models.UserFavorites if anthroveUserID == "" { - return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDIsEmpty} + return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} } if len(anthroveUserID) != 25 { - return nil, &errors2.EntityValidationFailed{Reason: errors2.AnthroveUserIDToShort} + return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort} } result := db.WithContext(ctx).Where("user_id = ?", string(anthroveUserID)).Find(&userFavorites) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &errors2.NoDataFound{} + return nil, &otterError.NoDataFound{} } return nil, result.Error } @@ -328,7 +328,7 @@ func GetUserTagWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthrov result = db.WithContext(ctx).Preload("Tags").First(&post, "id = ?", userFavorite.PostID) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &errors2.NoDataFound{} + return nil, &otterError.NoDataFound{} } return nil, result.Error } diff --git a/pkg/errors/database.go b/pkg/error/database.go similarity index 96% rename from pkg/errors/database.go rename to pkg/error/database.go index 5559b95..278a043 100644 --- a/pkg/errors/database.go +++ b/pkg/error/database.go @@ -1,4 +1,4 @@ -package errors +package error type EntityAlreadyExists struct{} diff --git a/pkg/errors/validation.go b/pkg/error/validation.go similarity index 95% rename from pkg/errors/validation.go rename to pkg/error/validation.go index 69efe47..889ae13 100644 --- a/pkg/errors/validation.go +++ b/pkg/error/validation.go @@ -1,4 +1,4 @@ -package errors +package error import "fmt" -- 2.45.1 From cb04347dd519875ca3e6bf2a7c6794c20bfc3523 Mon Sep 17 00:00:00 2001 From: SoXX Date: Wed, 26 Jun 2024 11:23:27 +0200 Subject: [PATCH 096/124] fix(errors): more tests Signed-off-by: SoXX --- internal/postgres/post_test.go | 9 ++ internal/postgres/relationships_test.go | 133 +++++++++++++++++++----- internal/postgres/source_test.go | 59 ++++++++++- internal/postgres/tag.go | 3 +- internal/postgres/tag_test.go | 72 ++++++++++++- internal/postgres/user.go | 9 +- internal/postgres/user_test.go | 90 +++++++++++++++- 7 files changed, 336 insertions(+), 39 deletions(-) diff --git a/internal/postgres/post_test.go b/internal/postgres/post_test.go index 99e5b32..fba733a 100644 --- a/internal/postgres/post_test.go +++ b/internal/postgres/post_test.go @@ -63,6 +63,15 @@ func TestCreateAnthrovePostNode(t *testing.T) { }, wantErr: true, }, + { + name: "Test 3: Nill", + args: args{ + ctx: context.Background(), + db: gormDB, + anthrovePost: nil, + }, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/postgres/relationships_test.go b/internal/postgres/relationships_test.go index a758ad2..dec686d 100644 --- a/internal/postgres/relationships_test.go +++ b/internal/postgres/relationships_test.go @@ -3,10 +3,11 @@ package postgres import ( "context" "fmt" + "testing" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/test" "gorm.io/gorm" - "testing" ) func TestCheckUserToPostLink(t *testing.T) { @@ -105,6 +106,28 @@ func TestCheckUserToPostLink(t *testing.T) { want: false, wantErr: true, }, + { + name: "Test 5: No AnthrovePostID given", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "", + anthrovePostID: "123456", + }, + want: false, + wantErr: true, + }, + { + name: "Test 6: No anthrovePostID given", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: invalidUserID, + anthrovePostID: "", + }, + want: false, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -120,7 +143,8 @@ func TestCheckUserToPostLink(t *testing.T) { } } -func TestEstablishAnthrovePostToSourceLink(t *testing.T) { +func TestCheckUserToPostLinkWithNoData(t *testing.T) { + // Setup trow away container ctx := context.Background() container, gormDB, err := test.StartPostgresContainer(ctx) @@ -130,9 +154,20 @@ func TestEstablishAnthrovePostToSourceLink(t *testing.T) { defer container.Terminate(ctx) // Setup Test + + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + invalidUserID := models.AnthroveUserID("XXX") + + validPostID := models.AnthrovePostID(fmt.Sprintf("%025s", "Post1")) + + err = CreateUser(ctx, gormDB, validUserID) + if err != nil { + t.Fatal(err) + } + post := &models.Post{ BaseModel: models.BaseModel[models.AnthrovePostID]{ - ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), + ID: validPostID, }, Rating: "safe", } @@ -142,74 +177,100 @@ func TestEstablishAnthrovePostToSourceLink(t *testing.T) { t.Fatal(err) } - source := &models.Source{ - DisplayName: "e621", - Domain: "e621.net", - Icon: "icon.e621.net", - } - err = CreateSource(ctx, gormDB, source) + err = CreateReferenceBetweenUserAndPost(ctx, gormDB, validUserID, post.ID) if err != nil { t.Fatal(err) } // Test type args struct { - ctx context.Context - db *gorm.DB - anthrovePostID models.AnthrovePostID - sourceDomain models.AnthroveSourceDomain - anthrovePostRelationship *models.PostReference + ctx context.Context + db *gorm.DB + anthroveUserID models.AnthroveUserID + anthrovePostID models.AnthrovePostID } tests := []struct { name string args args + want bool wantErr bool }{ { - name: "Test 1: Valid AnthrovePostID and anthroveSourceDomain", + name: "Test 1: Valid AnthroveUserID and AnthrovePostID", args: args{ ctx: ctx, db: gormDB, + anthroveUserID: validUserID, anthrovePostID: post.ID, - sourceDomain: "e621.net", }, + want: true, wantErr: false, }, { - name: "Test 2: Invalid AnthrovePostID and Valid anthroveSourceDomain", + name: "Test 2: Valid AnthroveUserID and invalid AnthrovePostID", args: args{ ctx: ctx, db: gormDB, + anthroveUserID: validUserID, + anthrovePostID: "qadw", + }, + want: false, + wantErr: true, + }, + { + name: "Test 3: Valid AnthrovePostID and invalid AnthroveUserID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: invalidUserID, + anthrovePostID: post.ID, + }, + want: false, + wantErr: true, + }, + { + name: "Test 4: Invalid AnthrovePostID and invalid AnthroveUserID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: invalidUserID, anthrovePostID: "123456", - sourceDomain: "e621.net", }, + want: false, wantErr: true, }, { - name: "Test 3: Invalid anthroveSourceDomain and Valid AnthrovePostID", + name: "Test 5: No AnthrovePostID given", args: args{ ctx: ctx, db: gormDB, - anthrovePostID: "1234", - sourceDomain: "fa.banana", + anthroveUserID: "", + anthrovePostID: "123456", }, + want: false, wantErr: true, }, { - name: "Test 4: Invalid anthroveSourceDomain and Invalid AnthrovePostID", + name: "Test 6: No anthrovePostID given", args: args{ ctx: ctx, db: gormDB, - anthrovePostID: "696969", - sourceDomain: "hehe.funny.number", + anthroveUserID: invalidUserID, + anthrovePostID: "", }, + want: false, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := CreateReferenceBetweenPostAndSource(tt.args.ctx, tt.args.db, tt.args.anthrovePostID, tt.args.sourceDomain); (err != nil) != tt.wantErr { - t.Errorf("CreateReferenceBetweenPostAndSource() error = %v, wantErr %v", err, tt.wantErr) + got, err := CheckReferenceBetweenUserAndPost(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.anthrovePostID) + if (err != nil) != tt.wantErr { + t.Errorf("CheckReferenceBetweenUserAndPost() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("CheckReferenceBetweenUserAndPost() got = %v, want %v", got, tt.want) } }) } @@ -300,6 +361,26 @@ func TestEstablishUserToPostLink(t *testing.T) { }, wantErr: true, }, + { + name: "Test 5: AnthrovePostID is empty", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: invalidUserID, + anthrovePostID: "", + }, + wantErr: true, + }, + { + name: "Test 6: anthroveUserID is empty", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "", + anthrovePostID: validPostID, + }, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/postgres/source_test.go b/internal/postgres/source_test.go index b618017..bcb38bd 100644 --- a/internal/postgres/source_test.go +++ b/internal/postgres/source_test.go @@ -3,10 +3,11 @@ package postgres import ( "context" "fmt" + "testing" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/test" "gorm.io/gorm" - "testing" ) func TestCreateSourceNode(t *testing.T) { @@ -30,7 +31,13 @@ func TestCreateSourceNode(t *testing.T) { } invalidSource := &models.Source{ - Domain: "", + BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: validPostID}, + Domain: "notfound.intern", + } + + invalidSourceDomain := &models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: validPostID}, + Domain: "", } // Test @@ -58,7 +65,7 @@ func TestCreateSourceNode(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveSource: invalidSource, + anthroveSource: invalidSourceDomain, }, wantErr: true, }, @@ -67,7 +74,7 @@ func TestCreateSourceNode(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - anthroveSource: validSource, + anthroveSource: invalidSource, }, wantErr: true, }, @@ -152,6 +159,50 @@ func TestGetAllSourceNodes(t *testing.T) { } } +func TestGetAllSourceWithNoData(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Test + type args struct { + ctx context.Context + db *gorm.DB + } + tests := []struct { + name string + args args + want []models.Source + wantErr bool + }{ + { + name: "Test 1: Get all entries", + args: args{ + ctx: ctx, + db: gormDB, + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetAllSource(tt.args.ctx, tt.args.db) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllSource() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !checkSourcesNode(got, tt.want) { + t.Errorf("GetAllSource() got = %v, want %v", got, tt.want) + } + }) + } +} + func TestGetSourceNodesByURL(t *testing.T) { // Setup trow away container ctx := context.Background() diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 93b5467..23e23ef 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -16,7 +16,7 @@ func CreateTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { return &otterError.EntityValidationFailed{Reason: "Tag is nil"} } - result := db.WithContext(ctx).Where(tag).Create(tag) + result := db.WithContext(ctx).Create(tag) if result.Error != nil { if errors.Is(result.Error, gorm.ErrDuplicatedKey) { return &otterError.EntityAlreadyExists{} @@ -77,7 +77,6 @@ func GetTags(ctx context.Context, db *gorm.DB) ([]models.Tag, error) { var tags []models.Tag result := db.WithContext(ctx).Find(&tags) - if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { return nil, &otterError.NoDataFound{} diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index a100774..045cd96 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -3,10 +3,11 @@ package postgres import ( "context" "fmt" + "testing" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/test" "gorm.io/gorm" - "testing" ) func TestCreateTagNodeWitRelation(t *testing.T) { @@ -54,7 +55,7 @@ func TestCreateTagNodeWitRelation(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - PostID: models.AnthrovePostID(post.ID), + PostID: post.ID, tag: tag, }, wantErr: false, @@ -64,7 +65,7 @@ func TestCreateTagNodeWitRelation(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - PostID: models.AnthrovePostID(post.ID), + PostID: post.ID, tag: nil, }, wantErr: true, @@ -180,3 +181,68 @@ func checkTag(got []models.Tag, want []models.Tag) bool { return true } + +func TestCreateTag(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validTag := models.Tag{ + Name: "JayTheFerret", + Type: "artist", + } + + invalidTag := models.Tag{} + + // Test + type args struct { + ctx context.Context + db *gorm.DB + tag *models.Tag + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid Tag", + args: args{ + ctx: ctx, + db: gormDB, + tag: &validTag, + }, + wantErr: false, + }, + { + name: "Test 2: Duplicate Tag", + args: args{ + ctx: ctx, + db: gormDB, + tag: &validTag, + }, + wantErr: true, + }, + { + name: "Test 3: Invalid Tag", + args: args{ + ctx: ctx, + db: gormDB, + tag: &invalidTag, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := CreateTag(tt.args.ctx, tt.args.db, tt.args.tag); (err != nil) != tt.wantErr { + t.Errorf("CreateTag() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 499911b..e10495e 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -34,6 +34,10 @@ func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Anthrove return result.Error } + if result.RowsAffected == 0 { + return &otterError.EntityAlreadyExists{} + } + return nil } @@ -325,7 +329,10 @@ func GetUserTagWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthrov for _, userFavorite := range userFavorites { var post models.Post - result = db.WithContext(ctx).Preload("Tags").First(&post, "id = ?", userFavorite.PostID) + result = db.WithContext(ctx).Preload("Tags", func(db *gorm.DB) *gorm.DB { + return db.Order("tag_type ASC") + }).First(&post, "id = ?", userFavorite.PostID) + if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { return nil, &otterError.NoDataFound{} diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index 3c63d8c..4477bea 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -54,6 +54,15 @@ func TestCreateUser(t *testing.T) { }, wantErr: true, }, + { + name: "Test 3: No anthroveUserID given", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "", + }, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -347,7 +356,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { wantErr: true, }, { - name: "Test 5: Valid AnthroveUserID and No SourceDisplayName", + name: "Test 5: Valid AnthroveUserID and No anthroveUserID", args: args{ ctx: ctx, db: gormDB, @@ -358,7 +367,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { wantErr: true, }, { - name: "Test 6: No AnthroveUserID and No SourceDisplayName", + name: "Test 6: No AnthroveUserID and No anthroveUserID", args: args{ ctx: ctx, db: gormDB, @@ -368,6 +377,17 @@ func TestGetUserSourceBySourceID(t *testing.T) { want: nil, wantErr: true, }, + { + name: "Test 7: No anthroveUserID given", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: validUserID, + sourceID: "", + }, + want: nil, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -505,6 +525,30 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { want: expectedResult3, wantErr: false, }, + { + name: "Test 4: No anthroveUserID given", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "", + skip: 0, + limit: 3, + }, + want: nil, + wantErr: true, + }, + { + name: "Test 5: Short anthroveUserID given", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "aaa", + skip: 0, + limit: 3, + }, + want: nil, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -725,6 +769,26 @@ func TestGetUserSourceLinks(t *testing.T) { want: expectedResult, wantErr: false, }, + { + name: "Test 3: No AnthroveID", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 1: AnthroveID to short", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "aaa", + }, + want: nil, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -772,7 +836,7 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { if err != nil { t.Fatal(err) } - err = CreateReferenceBetweenUserAndPost(ctx, gormDB, validAnthroveUserID, models.AnthrovePostID(post.ID)) + err = CreateReferenceBetweenUserAndPost(ctx, gormDB, validAnthroveUserID, post.ID) if err != nil { t.Fatal(err) } @@ -837,6 +901,26 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { want: expectedResult, wantErr: false, }, + { + name: "Test 2: No anthroveUserID given", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 3: short anthroveUserID given", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "aaa", + }, + want: nil, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { -- 2.45.1 From 615a6b1a25e8eddeabdfbd915a53adc256fa74a7 Mon Sep 17 00:00:00 2001 From: SoXX Date: Wed, 26 Jun 2024 11:31:42 +0200 Subject: [PATCH 097/124] fix(errors): fix unneeded error handling Signed-off-by: SoXX --- internal/postgres/source_test.go | 44 -------------------------------- internal/postgres/user.go | 5 +--- internal/postgres/user_test.go | 8 +++--- 3 files changed, 5 insertions(+), 52 deletions(-) diff --git a/internal/postgres/source_test.go b/internal/postgres/source_test.go index bcb38bd..dc5c58e 100644 --- a/internal/postgres/source_test.go +++ b/internal/postgres/source_test.go @@ -159,50 +159,6 @@ func TestGetAllSourceNodes(t *testing.T) { } } -func TestGetAllSourceWithNoData(t *testing.T) { - // Setup trow away container - ctx := context.Background() - container, gormDB, err := test.StartPostgresContainer(ctx) - if err != nil { - t.Fatalf("Could not start PostgreSQL container: %v", err) - } - defer container.Terminate(ctx) - - // Test - type args struct { - ctx context.Context - db *gorm.DB - } - tests := []struct { - name string - args args - want []models.Source - wantErr bool - }{ - { - name: "Test 1: Get all entries", - args: args{ - ctx: ctx, - db: gormDB, - }, - want: nil, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := GetAllSource(tt.args.ctx, tt.args.db) - if (err != nil) != tt.wantErr { - t.Errorf("GetAllSource() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !checkSourcesNode(got, tt.want) { - t.Errorf("GetAllSource() got = %v, want %v", got, tt.want) - } - }) - } -} - func TestGetSourceNodesByURL(t *testing.T) { // Setup trow away container ctx := context.Background() diff --git a/internal/postgres/user.go b/internal/postgres/user.go index e10495e..9346cb5 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -28,16 +28,13 @@ func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.Anthrove result := db.WithContext(ctx).FirstOrCreate(&user) if result.Error != nil { + if errors.Is(result.Error, gorm.ErrDuplicatedKey) { return &otterError.EntityAlreadyExists{} } return result.Error } - if result.RowsAffected == 0 { - return &otterError.EntityAlreadyExists{} - } - return nil } diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index 4477bea..dd0932b 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -707,7 +707,7 @@ func TestGetUserSourceLinks(t *testing.T) { } err = CreateSource(ctx, gormDB, eSource) if err != nil { - t.Fatal(err) + t.Fatal("Create Source e621:", err) } faSource := &models.Source{ @@ -717,7 +717,7 @@ func TestGetUserSourceLinks(t *testing.T) { } err = CreateSource(ctx, gormDB, faSource) if err != nil { - t.Fatal(err) + t.Fatal("Create Source fa:", err) } expectedResult := make(map[string]models.UserSource) @@ -740,11 +740,11 @@ func TestGetUserSourceLinks(t *testing.T) { err = CreateUserWithRelationToSource(ctx, gormDB, validAnthroveUserID, eSource.ID, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) if err != nil { - t.Fatal(err) + t.Fatal("CreateUserWithRelationToSource e621:", err) } err = CreateUserWithRelationToSource(ctx, gormDB, validAnthroveUserID, faSource.ID, expectedResult["fa"].UserID, expectedResult["fa"].AccountUsername) if err != nil { - t.Fatal(err) + t.Fatal("CreateUserWithRelationToSource fa:", err) } // Test -- 2.45.1 From a026563835604312e3f9e3b2a318caddbfa51c57 Mon Sep 17 00:00:00 2001 From: SoXX Date: Wed, 26 Jun 2024 11:48:25 +0200 Subject: [PATCH 098/124] fix(errors): added more tests Signed-off-by: SoXX --- pkg/error/database_test.go | 83 ++++++++++++++++++++++++++++++++++++ pkg/error/validation_test.go | 30 +++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 pkg/error/database_test.go create mode 100644 pkg/error/validation_test.go diff --git a/pkg/error/database_test.go b/pkg/error/database_test.go new file mode 100644 index 0000000..5fd2e1f --- /dev/null +++ b/pkg/error/database_test.go @@ -0,0 +1,83 @@ +package error + +import "testing" + +func TestEntityAlreadyExists_Error(t *testing.T) { + tests := []struct { + name string + want string + }{ + { + name: "Test : Valid error String", + want: "EntityAlreadyExists error", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + e := &EntityAlreadyExists{} + if got := e.Error(); got != tt.want { + t.Errorf("Error() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestNoDataFound_Error(t *testing.T) { + tests := []struct { + name string + want string + }{ + { + name: "Test : Valid error String", + want: "NoDataFound error", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + e := &NoDataFound{} + if got := e.Error(); got != tt.want { + t.Errorf("Error() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestNoDataWritten_Error(t *testing.T) { + tests := []struct { + name string + want string + }{ + { + name: "Test : Valid error String", + want: "NoDataWritten error", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + e := &NoDataWritten{} + if got := e.Error(); got != tt.want { + t.Errorf("Error() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestNoRelationCreated_Error(t *testing.T) { + tests := []struct { + name string + want string + }{ + { + name: "Test : Valid error String", + want: "relationship creation error", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + e := &NoRelationCreated{} + if got := e.Error(); got != tt.want { + t.Errorf("Error() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/error/validation_test.go b/pkg/error/validation_test.go new file mode 100644 index 0000000..88e9d3c --- /dev/null +++ b/pkg/error/validation_test.go @@ -0,0 +1,30 @@ +package error + +import "testing" + +func TestEntityValidationFailed_Error(t *testing.T) { + type fields struct { + Reason string + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "Test 1: Reason", + fields: fields{Reason: "TEST ERROR"}, + want: "Entity validation failed: TEST ERROR", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + e := EntityValidationFailed{ + Reason: tt.fields.Reason, + } + if got := e.Error(); got != tt.want { + t.Errorf("Error() = %v, want %v", got, tt.want) + } + }) + } +} -- 2.45.1 From 0a5359d7231fec6a28ec9aebfb6a5be093c49226 Mon Sep 17 00:00:00 2001 From: SoXX Date: Wed, 26 Jun 2024 12:07:55 +0200 Subject: [PATCH 099/124] ci: fix go command to show in log Signed-off-by: SoXX --- .gitea/workflows/ build_check.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/ build_check.yaml b/.gitea/workflows/ build_check.yaml index 5a50130..cede029 100644 --- a/.gitea/workflows/ build_check.yaml +++ b/.gitea/workflows/ build_check.yaml @@ -28,7 +28,7 @@ jobs: cache: true # optional - name: Execute Go Test files with coverage report - run: go test -v ./... -json -coverprofile="coverage.out" > "test-report.out" + run: go test -v ./... -json -coverprofile="coverage.out" | tee "test-report.out" - uses: sonarsource/sonarqube-scan-action@master env: -- 2.45.1 From 97d314ba3e44babc74e92d6109a96d68affed68d Mon Sep 17 00:00:00 2001 From: SoXX Date: Wed, 26 Jun 2024 12:20:38 +0200 Subject: [PATCH 100/124] ci: fix go command to show in log Signed-off-by: SoXX --- .gitea/workflows/ build_check.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/ build_check.yaml b/.gitea/workflows/ build_check.yaml index cede029..4d35c68 100644 --- a/.gitea/workflows/ build_check.yaml +++ b/.gitea/workflows/ build_check.yaml @@ -28,7 +28,7 @@ jobs: cache: true # optional - name: Execute Go Test files with coverage report - run: go test -v ./... -json -coverprofile="coverage.out" | tee "test-report.out" + run: TESTCONTAINERS_RYUK_DISABLED=true go test -v ./... -json -coverprofile="coverage.out" | tee "test-report.out" - uses: sonarsource/sonarqube-scan-action@master env: -- 2.45.1 From a9a21581bdac2966972a445a5e27d90fd938aa8d Mon Sep 17 00:00:00 2001 From: SoXX Date: Wed, 26 Jun 2024 12:40:59 +0200 Subject: [PATCH 101/124] test(helper): extend the waiting time to 10 seconds Signed-off-by: SoXX --- test/helper.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/helper.go b/test/helper.go index 6fed12e..bb3f057 100644 --- a/test/helper.go +++ b/test/helper.go @@ -3,16 +3,17 @@ package test import ( "context" "database/sql" + "net/url" + "strconv" + "strings" + "time" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" migrate "github.com/rubenv/sql-migrate" postgrescontainer "github.com/testcontainers/testcontainers-go/modules/postgres" "gorm.io/driver/postgres" "gorm.io/gorm" "gorm.io/gorm/logger" - "net/url" - "strconv" - "strings" - "time" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" @@ -34,7 +35,7 @@ func StartPostgresContainer(ctx context.Context) (*postgrescontainer.PostgresCon postgrescontainer.WithPassword(databasePassword), testcontainers.WithWaitStrategy( wait.ForLog("database system is ready to accept connections"). - WithOccurrence(2).WithStartupTimeout(5*time.Second)), + WithOccurrence(2).WithStartupTimeout(10*time.Second)), ) if err != nil { return nil, nil, err -- 2.45.1 From e29cea6e3cb8a768186984ba0aa736f8f5a0f04e Mon Sep 17 00:00:00 2001 From: SoXX Date: Wed, 26 Jun 2024 16:12:10 +0200 Subject: [PATCH 102/124] feat(functions): enhanced function with RAW SQL Signed-off-by: SoXX --- internal/postgres/relationships.go | 22 +++------- internal/postgres/user.go | 41 ++++++------------- pkg/database/database.go | 2 +- .../migrations/001_inital_database.sql | 2 +- pkg/database/postgres.go | 6 +-- pkg/models/const.go | 1 + 6 files changed, 23 insertions(+), 51 deletions(-) diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index 8aa1079..5e8e8e6 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -10,9 +10,7 @@ import ( "gorm.io/gorm" ) -func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain) error { - var source models.Source - +func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL) error { if anthrovePostID == "" { return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} } @@ -25,26 +23,16 @@ func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthr return &otterError.EntityValidationFailed{Reason: "sourceDomain cannot be empty"} } - // Find the source - result := db.WithContext(ctx).Where("domain = ?", sourceDomain).First(&source) + result := db.WithContext(ctx).Exec(`INSERT INTO "PostReference" (post_id, source_id, url) SELECT $1, source.id, $2 FROM "Source" AS source WHERE domain = $3;`, anthrovePostID, postURL, sourceDomain) + if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { return &otterError.NoDataFound{} } - return result.Error - } - - // Establish the relationship - result = db.WithContext(ctx).Create(models.PostReference{ - PostID: string(anthrovePostID), - SourceID: string(source.ID), - URL: string(sourceDomain), - }) - - if result.Error != nil { - if errors.Is(result.Error, gorm.ErrDuplicatedKey) { + if errors.Is(result.Error, gorm.ErrCheckConstraintViolated) { return &otterError.EntityAlreadyExists{} } + return result.Error } diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 9346cb5..404c32c 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -56,46 +56,29 @@ func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUs return &otterError.EntityValidationFailed{Reason: "accountUsername cannot be empty"} } - err := CreateUser(ctx, db, anthroveUserID) - if err != nil { - return err - } + result := db.WithContext(ctx).Exec(`WITH userObj AS ( + INSERT INTO "User" (id) + VALUES ($1) + ON CONFLICT (id) DO NOTHING + ) + INSERT INTO "UserSource" (user_id, source_id, account_username, account_id) + SELECT $2, source.id, $3, $4 + FROM "Source" AS source + WHERE source.id = $5;`, anthroveUserID, anthroveUserID, accountUsername, accountId, sourceID) - source := models.Source{ - BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: sourceID}, - } - - result := db.WithContext(ctx).Where(&source).First(&source) if result.Error != nil { - if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return &otterError.NoDataFound{} + if errors.Is(result.Error, gorm.ErrDuplicatedKey) { + return &otterError.EntityAlreadyExists{} } return result.Error } - userSource := models.UserSource{ - User: models.User{BaseModel: models.BaseModel[models.AnthroveUserID]{ID: anthroveUserID}}, - SourceID: string(source.ID), - AccountUsername: accountUsername, - AccountID: accountId, - UserID: string(anthroveUserID), - } - - result = db.WithContext(ctx).FirstOrCreate(&userSource) - if result.Error != nil { - return errors.Join(result.Error, &otterError.NoRelationCreated{}) - } - - if result.RowsAffected == 0 { - return &otterError.NoDataWritten{} - } - log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, "source_id": sourceID, "account_username": accountUsername, "account_id": accountId, - }).Trace("database: created user-source relationship") + }).Info("database: created user-source relationship") return nil } diff --git a/pkg/database/database.go b/pkg/database/database.go index 10d203a..f8be8ef 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -23,7 +23,7 @@ type OtterSpace interface { CreateTagAndReferenceToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error // CreateReferenceBetweenPostAndSource links a post with a source. - CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain) error + CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL) error // CreateReferenceBetweenUserAndPost links a user with a post. CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error diff --git a/pkg/database/migrations/001_inital_database.sql b/pkg/database/migrations/001_inital_database.sql index e6758e3..d580538 100644 --- a/pkg/database/migrations/001_inital_database.sql +++ b/pkg/database/migrations/001_inital_database.sql @@ -95,7 +95,7 @@ CREATE TABLE "UserSource" account_username TEXT, account_id TEXT, PRIMARY KEY (user_id, source_id), - UNIQUE (account_username, account_id) + UNIQUE (source_id, account_username, account_id) ); CREATE TABLE "post_tags" diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 4245c9b..676d308 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -47,7 +47,7 @@ func (p *postgresqlConnection) Connect(_ context.Context, config models.Database dbLogger := logger2.New(log2.New(os.Stdout, "\r\n", log2.LstdFlags), logger2.Config{ SlowThreshold: 200 * time.Millisecond, - LogLevel: logger2.Warn, + LogLevel: logger2.Info, IgnoreRecordNotFoundError: true, Colorful: true, }) @@ -88,8 +88,8 @@ func (p *postgresqlConnection) CreateTagAndReferenceToPost(ctx context.Context, return postgres.CreateTagAndReferenceToPost(ctx, p.db, anthrovePostID, anthroveTag) } -func (p *postgresqlConnection) CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain) error { - return postgres.CreateReferenceBetweenPostAndSource(ctx, p.db, anthrovePostID, sourceDomain) +func (p *postgresqlConnection) CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL) error { + return postgres.CreateReferenceBetweenPostAndSource(ctx, p.db, anthrovePostID, sourceDomain, postURL) } func (p *postgresqlConnection) CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error { diff --git a/pkg/models/const.go b/pkg/models/const.go index 5b0e59a..f95434f 100644 --- a/pkg/models/const.go +++ b/pkg/models/const.go @@ -4,6 +4,7 @@ type AnthroveUserID string type AnthrovePostID string type AnthroveSourceID string type AnthroveSourceDomain string +type AnthrovePostURL string type Rating string type TagType string -- 2.45.1 From a71f75976325e21177110ac93174f2274552ca3b Mon Sep 17 00:00:00 2001 From: SoXX Date: Thu, 27 Jun 2024 16:11:16 +0200 Subject: [PATCH 103/124] feat(functions): fixing bugs Signed-off-by: SoXX --- internal/postgres/post_test.go | 7 ++-- internal/postgres/user.go | 59 ++++++++++++---------------------- internal/postgres/user_test.go | 28 +++++++++------- pkg/database/database.go | 2 +- 4 files changed, 41 insertions(+), 55 deletions(-) diff --git a/internal/postgres/post_test.go b/internal/postgres/post_test.go index fba733a..735f6b5 100644 --- a/internal/postgres/post_test.go +++ b/internal/postgres/post_test.go @@ -176,6 +176,7 @@ func TestGetPostBySourceURL(t *testing.T) { BaseModel: models.BaseModel[models.AnthrovePostID]{ ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")), }, + Rating: "safe", } @@ -198,7 +199,7 @@ func TestGetPostBySourceURL(t *testing.T) { t.Fatal("Could not create source", err) } - err = CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain)) + err = CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain), "http://test.org") if err != nil { t.Fatal("Could not create source reference", err) } @@ -220,7 +221,7 @@ func TestGetPostBySourceURL(t *testing.T) { args: args{ ctx: ctx, db: gormDB, - sourceURL: source.Domain, + sourceURL: "http://test.org", }, want: post, wantErr: false, @@ -297,7 +298,7 @@ func TestGetPostBySourceID(t *testing.T) { t.Fatal("Could not create source", err) } - err = CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain)) + err = CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain), "http://test.otg") if err != nil { t.Fatal("Could not create source reference", err) } diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 404c32c..aa5d5a5 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -283,8 +283,15 @@ func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUse return &models.FavoriteList{Posts: favoritePosts}, nil } +// Workaround, should be changed later maybe, but its not that bad right now +type selectFrequencyTag struct { + tagName string `gorm:"tag_name"` + count int64 `gorm:"count"` + tagType models.TagType `gorm:"tag_type"` +} + func GetUserTagWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { - var userFavorites []models.UserFavorites + var queryUserFavorites []selectFrequencyTag if anthroveUserID == "" { return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} @@ -294,7 +301,11 @@ func GetUserTagWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthrov return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort} } - result := db.WithContext(ctx).Where("user_id = ?", string(anthroveUserID)).Find(&userFavorites) + result := db.WithContext(ctx).Raw( + `WITH user_posts AS ( + SELECT post_id FROM "UserFavorites" WHERE user_id = $1 + ) + SELECT post_tags.tag_name AS tag_name, count(*) AS count, (SELECT tag_type FROM "Tag" WHERE "Tag".name = post_tags.tag_name LIMIT 1) AS tag_type FROM post_tags, user_posts WHERE post_tags.post_id IN (user_posts.post_id) GROUP BY post_tags.tag_name`, anthroveUserID).Scan(&queryUserFavorites) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { return nil, &otterError.NoDataFound{} @@ -302,47 +313,17 @@ func GetUserTagWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthrov return nil, result.Error } - tagFrequency := make(map[struct { - name string - typeName string - }]int) - - for _, userFavorite := range userFavorites { - var post models.Post - result = db.WithContext(ctx).Preload("Tags", func(db *gorm.DB) *gorm.DB { - return db.Order("tag_type ASC") - }).First(&post, "id = ?", userFavorite.PostID) - - if result.Error != nil { - if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &otterError.NoDataFound{} - } - return nil, result.Error - } - - for _, tag := range post.Tags { - tagFrequency[struct { - name string - typeName string - }{name: tag.Name, typeName: string(tag.Type)}]++ - } - } - - var tagsWithFrequency []models.TagsWithFrequency - for data, frequency := range tagFrequency { - tagsWithFrequency = append(tagsWithFrequency, models.TagsWithFrequency{ - Frequency: int64(frequency), - Tags: models.Tag{ - Name: data.name, - Type: models.TagType(data.typeName), - }, - }) + var userFavoritesFrequency = make([]models.TagsWithFrequency, len(queryUserFavorites)) + for i, query := range queryUserFavorites { + userFavoritesFrequency[i].Frequency = query.count + userFavoritesFrequency[i].Tags.Name = query.tagName + userFavoritesFrequency[i].Tags.Type = query.tagType } log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, - "tag_amount": len(tagsWithFrequency), + "tag_amount": len(queryUserFavorites), }).Trace("database: got user tag node with relation to faved posts") - return tagsWithFrequency, nil + return userFavoritesFrequency, nil } diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index dd0932b..168829a 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -162,7 +162,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { userID: "e1", username: "marius", }, - wantErr: true, + wantErr: false, }, { name: "Test 5: no userID", @@ -270,30 +270,33 @@ func TestGetUserSourceBySourceID(t *testing.T) { validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) invalidUserID := models.AnthroveUserID("XXX") + validSourceID := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source1")) + + source := &models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ + ID: validSourceID, + }, + DisplayName: "e621", + Domain: "e621.net", + } + expectedResult := make(map[string]models.UserSource) expectedResult["e621"] = models.UserSource{ UserID: "e1", AccountUsername: "euser", Source: models.Source{ - DisplayName: "e621", - Domain: "e621.net", + DisplayName: source.DisplayName, + Domain: source.Domain, + Icon: source.Icon, }, } - source := &models.Source{ - BaseModel: models.BaseModel[models.AnthroveSourceID]{ - ID: expectedResult["e621"].Source.ID, - }, - DisplayName: expectedResult["e621"].Source.DisplayName, - Domain: expectedResult["e621"].Source.Domain, - } - err = CreateSource(ctx, gormDB, source) if err != nil { t.Fatal(err) } - err = CreateUserWithRelationToSource(ctx, gormDB, validUserID, models.AnthroveSourceID(expectedResult["e621"].SourceID), expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) + err = CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) if err != nil { t.Fatal(err) } @@ -389,6 +392,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { wantErr: true, }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := GetUserSourceBySourceID(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.sourceID) diff --git a/pkg/database/database.go b/pkg/database/database.go index f8be8ef..0060744 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -35,7 +35,7 @@ type OtterSpace interface { GetPostByAnthroveID(ctx context.Context, anthrovePostID models.AnthrovePostID) (*models.Post, error) // GetPostByURL retrieves a post by its source URL. - GetPostByURL(ctx context.Context, sourceUrl string) (*models.Post, error) + GetPostByURL(ctx context.Context, postURL string) (*models.Post, error) // GetPostBySourceID retrieves a post by its source ID. GetPostBySourceID(ctx context.Context, sourceID models.AnthroveSourceID) (*models.Post, error) -- 2.45.1 From da4fda3597e39951b9de9e4a693b4d890a255b19 Mon Sep 17 00:00:00 2001 From: SoXX Date: Thu, 27 Jun 2024 21:37:29 +0200 Subject: [PATCH 104/124] refactor(postgres): a lot of things happened here Signed-off-by: SoXX --- internal/postgres/user.go | 37 +++++++++++++++++--------- internal/postgres/user_test.go | 8 +++--- pkg/database/postgres_test.go | 48 ++++++++++++++++++++-------------- 3 files changed, 57 insertions(+), 36 deletions(-) diff --git a/internal/postgres/user.go b/internal/postgres/user.go index aa5d5a5..d7b365a 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -73,6 +73,10 @@ func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUs return result.Error } + if result.RowsAffected == 0 { + return &otterError.NoDataWritten{} + } + log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, "source_id": sourceID, @@ -301,23 +305,32 @@ func GetUserTagWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthrov return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort} } - result := db.WithContext(ctx).Raw( + rows, err := db.WithContext(ctx).Raw( `WITH user_posts AS ( - SELECT post_id FROM "UserFavorites" WHERE user_id = $1 - ) - SELECT post_tags.tag_name AS tag_name, count(*) AS count, (SELECT tag_type FROM "Tag" WHERE "Tag".name = post_tags.tag_name LIMIT 1) AS tag_type FROM post_tags, user_posts WHERE post_tags.post_id IN (user_posts.post_id) GROUP BY post_tags.tag_name`, anthroveUserID).Scan(&queryUserFavorites) - if result.Error != nil { - if errors.Is(result.Error, gorm.ErrRecordNotFound) { + SELECT post_id FROM "UserFavorites" WHERE user_id = $1 + ) + SELECT post_tags.tag_name AS tag_name, count(*) AS count, (SELECT tag_type FROM "Tag" WHERE "Tag".name = post_tags.tag_name LIMIT 1) AS tag_type FROM post_tags, user_posts WHERE post_tags.post_id IN (user_posts.post_id) GROUP BY post_tags.tag_name ORDER BY tag_type DESC, tag_name DESC`, anthroveUserID).Rows() + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { return nil, &otterError.NoDataFound{} } - return nil, result.Error + return nil, err } - var userFavoritesFrequency = make([]models.TagsWithFrequency, len(queryUserFavorites)) - for i, query := range queryUserFavorites { - userFavoritesFrequency[i].Frequency = query.count - userFavoritesFrequency[i].Tags.Name = query.tagName - userFavoritesFrequency[i].Tags.Type = query.tagType + var userFavoritesFrequency = make([]models.TagsWithFrequency, 0) + defer rows.Close() + for rows.Next() { + var tagName string + var count int64 + var tagType string + rows.Scan(&tagName, &count, &tagType) + userFavoritesFrequency = append(userFavoritesFrequency, models.TagsWithFrequency{ + Frequency: count, + Tags: models.Tag{ + Name: tagName, + Type: models.TagType(tagType), + }, + }) } log.WithFields(log.Fields{ diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index 168829a..ea9f2ad 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -870,15 +870,15 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { { Frequency: 1, Tags: models.Tag{ - Name: tags[1].Name, - Type: tags[1].Type, + Name: tags[2].Name, + Type: tags[2].Type, }, }, { Frequency: 1, Tags: models.Tag{ - Name: tags[2].Name, - Type: tags[2].Type, + Name: tags[1].Name, + Type: tags[1].Type, }, }, } diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index 4103607..bef6428 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -469,6 +469,7 @@ func Test_postgresqlConnection_CreateReferenceBetweenPostAndSource(t *testing.T) ctx context.Context anthrovePostID models.AnthrovePostID sourceDomain models.AnthroveSourceDomain + postURl models.AnthrovePostURL } tests := []struct { name string @@ -481,6 +482,7 @@ func Test_postgresqlConnection_CreateReferenceBetweenPostAndSource(t *testing.T) ctx: ctx, anthrovePostID: post.ID, sourceDomain: "e621.net", + postURl: "http://e621.net/post/eeasd", }, wantErr: false, }, @@ -490,6 +492,7 @@ func Test_postgresqlConnection_CreateReferenceBetweenPostAndSource(t *testing.T) ctx: ctx, anthrovePostID: "123456", sourceDomain: "e621.net", + postURl: "", }, wantErr: true, }, @@ -499,6 +502,7 @@ func Test_postgresqlConnection_CreateReferenceBetweenPostAndSource(t *testing.T) ctx: ctx, anthrovePostID: "1234", sourceDomain: "fa.banana", + postURl: "", }, wantErr: true, }, @@ -507,7 +511,7 @@ func Test_postgresqlConnection_CreateReferenceBetweenPostAndSource(t *testing.T) args: args{ ctx: ctx, anthrovePostID: "696969", - sourceDomain: "hehe.funny.number", + postURl: "", }, wantErr: true, }} @@ -517,7 +521,7 @@ func Test_postgresqlConnection_CreateReferenceBetweenPostAndSource(t *testing.T) db: gormDB, debug: true, } - if err := p.CreateReferenceBetweenPostAndSource(tt.args.ctx, tt.args.anthrovePostID, tt.args.sourceDomain); (err != nil) != tt.wantErr { + if err := p.CreateReferenceBetweenPostAndSource(tt.args.ctx, tt.args.anthrovePostID, tt.args.sourceDomain, tt.args.postURl); (err != nil) != tt.wantErr { t.Errorf("CreateReferenceBetweenPostAndSource() error = %v, wantErr %v", err, tt.wantErr) } }) @@ -830,7 +834,7 @@ func Test_postgresqlConnection_GetPostByURL(t *testing.T) { t.Fatal("Could not create source", err) } - err = postgres.CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain)) + err = postgres.CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain), "https://e62asdwad.com/asdas") if err != nil { t.Fatal("Could not create source reference", err) } @@ -850,7 +854,7 @@ func Test_postgresqlConnection_GetPostByURL(t *testing.T) { name: "Test 1: Valid sourceUrl", args: args{ ctx: ctx, - sourceUrl: source.Domain, + sourceUrl: "https://e62asdwad.com/asdas", }, want: post, wantErr: false, @@ -931,7 +935,7 @@ func Test_postgresqlConnection_GetPostBySourceID(t *testing.T) { t.Fatal("Could not create source", err) } - err = postgres.CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain)) + err = postgres.CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain), "https://easd15aed.de/asd") if err != nil { t.Fatal("Could not create source reference", err) } @@ -1228,30 +1232,34 @@ func Test_postgresqlConnection_GetUserSourceBySourceID(t *testing.T) { validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) invalidUserID := models.AnthroveUserID("XXX") + validSourceID := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source1")) + expectedResult := make(map[string]models.UserSource) + + source := &models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ + ID: validSourceID, + }, + DisplayName: "e621", + Domain: "e621.net", + } + expectedResult["e621"] = models.UserSource{ UserID: "e1", AccountUsername: "euser", Source: models.Source{ - DisplayName: "e621", - Domain: "e621.net", + DisplayName: source.DisplayName, + Domain: source.Domain, + Icon: source.Icon, }, } - source := &models.Source{ - BaseModel: models.BaseModel[models.AnthroveSourceID]{ - ID: expectedResult["e621"].Source.ID, - }, - DisplayName: expectedResult["e621"].Source.DisplayName, - Domain: expectedResult["e621"].Source.Domain, - } - err = postgres.CreateSource(ctx, gormDB, source) if err != nil { t.Fatal(err) } - err = postgres.CreateUserWithRelationToSource(ctx, gormDB, validUserID, models.AnthroveSourceID(expectedResult["e621"].SourceID), expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) + err = postgres.CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) if err != nil { t.Fatal(err) } @@ -1605,15 +1613,15 @@ func Test_postgresqlConnection_GetUserTagWitRelationToFavedPosts(t *testing.T) { { Frequency: 1, Tags: models.Tag{ - Name: tags[1].Name, - Type: tags[1].Type, + Name: tags[2].Name, + Type: tags[2].Type, }, }, { Frequency: 1, Tags: models.Tag{ - Name: tags[2].Name, - Type: tags[2].Type, + Name: tags[1].Name, + Type: tags[1].Type, }, }, } -- 2.45.1 From 56bb414f9df6786a44299b3982d73af52855520d Mon Sep 17 00:00:00 2001 From: SoXX Date: Thu, 27 Jun 2024 22:05:21 +0200 Subject: [PATCH 105/124] feat(PostReference): added the ability to add missing filed in db Signed-off-by: SoXX --- internal/postgres/post_test.go | 4 ++-- internal/postgres/relationships.go | 4 ++-- internal/postgres/user_test.go | 2 +- pkg/database/database.go | 12 +++++++++++- pkg/database/postgres.go | 4 ++-- pkg/database/postgres_test.go | 6 +++--- pkg/models/postReference.go | 10 +++++++--- 7 files changed, 28 insertions(+), 14 deletions(-) diff --git a/internal/postgres/post_test.go b/internal/postgres/post_test.go index 735f6b5..f679eaa 100644 --- a/internal/postgres/post_test.go +++ b/internal/postgres/post_test.go @@ -199,7 +199,7 @@ func TestGetPostBySourceURL(t *testing.T) { t.Fatal("Could not create source", err) } - err = CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain), "http://test.org") + err = CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain), "http://test.org", models.PostReferenceConfig{}) if err != nil { t.Fatal("Could not create source reference", err) } @@ -298,7 +298,7 @@ func TestGetPostBySourceID(t *testing.T) { t.Fatal("Could not create source", err) } - err = CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain), "http://test.otg") + err = CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain), "http://test.otg", models.PostReferenceConfig{}) if err != nil { t.Fatal("Could not create source reference", err) } diff --git a/internal/postgres/relationships.go b/internal/postgres/relationships.go index 5e8e8e6..bda9569 100644 --- a/internal/postgres/relationships.go +++ b/internal/postgres/relationships.go @@ -10,7 +10,7 @@ import ( "gorm.io/gorm" ) -func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL) error { +func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL, config models.PostReferenceConfig) error { if anthrovePostID == "" { return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} } @@ -23,7 +23,7 @@ func CreateReferenceBetweenPostAndSource(ctx context.Context, db *gorm.DB, anthr return &otterError.EntityValidationFailed{Reason: "sourceDomain cannot be empty"} } - result := db.WithContext(ctx).Exec(`INSERT INTO "PostReference" (post_id, source_id, url) SELECT $1, source.id, $2 FROM "Source" AS source WHERE domain = $3;`, anthrovePostID, postURL, sourceDomain) + result := db.WithContext(ctx).Exec(`INSERT INTO "PostReference" (post_id, source_id, url, full_file_url, preview_file_url, sample_file_url, source_post_id) SELECT $1, source.id, $2, $4, $5, $6, $7 FROM "Source" AS source WHERE domain = $3;`, anthrovePostID, postURL, sourceDomain, config.FullFileURL, config.PreviewFileURL, config.SampleFileURL, config.SourcePostID) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index ea9f2ad..b146d52 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -162,7 +162,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { userID: "e1", username: "marius", }, - wantErr: false, + wantErr: true, }, { name: "Test 5: no userID", diff --git a/pkg/database/database.go b/pkg/database/database.go index 0060744..fc2e5ed 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -23,7 +23,7 @@ type OtterSpace interface { CreateTagAndReferenceToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error // CreateReferenceBetweenPostAndSource links a post with a source. - CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL) error + CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL, config models.PostReferenceConfig) error // CreateReferenceBetweenUserAndPost links a user with a post. CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error @@ -66,4 +66,14 @@ type OtterSpace interface { // GetSourceByDomain retrieves a source by its URL. GetSourceByDomain(ctx context.Context, sourceDomain models.AnthroveSourceDomain) (*models.Source, error) + /* + CreateTagAlias() + DeleteTagAlias() + UpdateTagWithAlias() + + CreateTagGroup() + DeleteTagGroup() + UpdateTagWithGroup() + + UpdateUserWithScrapeTimeInterval()*/ } diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 676d308..fb53ec9 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -88,8 +88,8 @@ func (p *postgresqlConnection) CreateTagAndReferenceToPost(ctx context.Context, return postgres.CreateTagAndReferenceToPost(ctx, p.db, anthrovePostID, anthroveTag) } -func (p *postgresqlConnection) CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL) error { - return postgres.CreateReferenceBetweenPostAndSource(ctx, p.db, anthrovePostID, sourceDomain, postURL) +func (p *postgresqlConnection) CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL, config models.PostReferenceConfig) error { + return postgres.CreateReferenceBetweenPostAndSource(ctx, p.db, anthrovePostID, sourceDomain, postURL, config) } func (p *postgresqlConnection) CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error { diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index bef6428..c7d4996 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -521,7 +521,7 @@ func Test_postgresqlConnection_CreateReferenceBetweenPostAndSource(t *testing.T) db: gormDB, debug: true, } - if err := p.CreateReferenceBetweenPostAndSource(tt.args.ctx, tt.args.anthrovePostID, tt.args.sourceDomain, tt.args.postURl); (err != nil) != tt.wantErr { + if err := p.CreateReferenceBetweenPostAndSource(tt.args.ctx, tt.args.anthrovePostID, tt.args.sourceDomain, tt.args.postURl, models.PostReferenceConfig{}); (err != nil) != tt.wantErr { t.Errorf("CreateReferenceBetweenPostAndSource() error = %v, wantErr %v", err, tt.wantErr) } }) @@ -834,7 +834,7 @@ func Test_postgresqlConnection_GetPostByURL(t *testing.T) { t.Fatal("Could not create source", err) } - err = postgres.CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain), "https://e62asdwad.com/asdas") + err = postgres.CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain), "https://e62asdwad.com/asdas", models.PostReferenceConfig{}) if err != nil { t.Fatal("Could not create source reference", err) } @@ -935,7 +935,7 @@ func Test_postgresqlConnection_GetPostBySourceID(t *testing.T) { t.Fatal("Could not create source", err) } - err = postgres.CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain), "https://easd15aed.de/asd") + err = postgres.CreateReferenceBetweenPostAndSource(ctx, gormDB, post.ID, models.AnthroveSourceDomain(source.Domain), "https://easd15aed.de/asd", models.PostReferenceConfig{}) if err != nil { t.Fatal("Could not create source reference", err) } diff --git a/pkg/models/postReference.go b/pkg/models/postReference.go index 999e145..df1267c 100644 --- a/pkg/models/postReference.go +++ b/pkg/models/postReference.go @@ -1,9 +1,13 @@ package models type PostReference struct { - PostID string `gorm:"primaryKey"` - SourceID string `gorm:"primaryKey"` - URL string `gorm:"not null;unique"` + PostID string `gorm:"primaryKey"` + SourceID string `gorm:"primaryKey"` + URL string `gorm:"not null;unique"` + PostReferenceConfig +} + +type PostReferenceConfig struct { SourcePostID string FullFileURL string PreviewFileURL string -- 2.45.1 From 51aa79e4c26ffc9908c6666adb961a5f1989221a Mon Sep 17 00:00:00 2001 From: SoXX Date: Thu, 27 Jun 2024 22:17:25 +0200 Subject: [PATCH 106/124] feat(newAPIs): initial structure for new api endpoints Signed-off-by: SoXX --- pkg/database/database.go | 19 +++++++++-------- pkg/database/postgres.go | 45 ++++++++++++++++++++++++++++++++++++++++ pkg/models/const.go | 6 ++++++ 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/pkg/database/database.go b/pkg/database/database.go index fc2e5ed..3f739b4 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -2,7 +2,6 @@ package database import ( "context" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" ) @@ -66,14 +65,16 @@ type OtterSpace interface { // GetSourceByDomain retrieves a source by its URL. GetSourceByDomain(ctx context.Context, sourceDomain models.AnthroveSourceDomain) (*models.Source, error) - /* - CreateTagAlias() - DeleteTagAlias() - UpdateTagWithAlias() - CreateTagGroup() - DeleteTagGroup() - UpdateTagWithGroup() + GetAllTagAlias(ctx context.Context) ([]models.TagAlias, error) + GetAllTagAliasByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagAlias, error) + CreateTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName, tagID models.AnthroveTagID) error + DeleteTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName) error - UpdateUserWithScrapeTimeInterval()*/ + GetAllTagGroup(ctx context.Context) ([]models.TagGroup, error) + GetAllTagGroupByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagGroup, error) + CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) + DeleteTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName) error + + UpdateUserWithScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error } diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index fb53ec9..1770610 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -148,6 +148,51 @@ func (p *postgresqlConnection) GetSourceByDomain(ctx context.Context, sourceDoma return postgres.GetSourceByDomain(ctx, p.db, sourceDomain) } +func (p *postgresqlConnection) GetAllTagAlias(ctx context.Context) ([]models.TagAlias, error) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) GetAllTagAliasByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagAlias, error) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) CreateTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName, tagID models.AnthroveTagID) error { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) DeleteTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName) error { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) GetAllTagGroup(ctx context.Context) ([]models.TagGroup, error) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) GetAllTagGroupByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagGroup, error) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) DeleteTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName) error { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) UpdateUserWithScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error { + //TODO implement me + panic("implement me") +} + func (p *postgresqlConnection) migrateDatabase(dbPool *gorm.DB) error { dialect := "postgres" migrations := &migrate.EmbedFileSystemMigrationSource{FileSystem: embedMigrations, Root: "migrations"} diff --git a/pkg/models/const.go b/pkg/models/const.go index f95434f..13646fe 100644 --- a/pkg/models/const.go +++ b/pkg/models/const.go @@ -1,10 +1,16 @@ package models +import "google.golang.org/genproto/googleapis/type/date" + type AnthroveUserID string type AnthrovePostID string type AnthroveSourceID string type AnthroveSourceDomain string type AnthrovePostURL string +type AnthroveTagGroupName string +type AnthroveTagAliasName string +type AnthroveTagID string +type AnthroveScrapeTimeInterval date.Date type Rating string type TagType string -- 2.45.1 From 9c8a7c1e16fdf7ab6a887282ef93f8fc85ae4237 Mon Sep 17 00:00:00 2001 From: SoXX Date: Thu, 27 Jun 2024 22:18:35 +0200 Subject: [PATCH 107/124] fix(tests): remove timeout Signed-off-by: SoXX --- test/helper.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/test/helper.go b/test/helper.go index bb3f057..93a185e 100644 --- a/test/helper.go +++ b/test/helper.go @@ -3,17 +3,15 @@ package test import ( "context" "database/sql" - "net/url" - "strconv" - "strings" - "time" - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" migrate "github.com/rubenv/sql-migrate" postgrescontainer "github.com/testcontainers/testcontainers-go/modules/postgres" "gorm.io/driver/postgres" "gorm.io/gorm" "gorm.io/gorm/logger" + "net/url" + "strconv" + "strings" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" @@ -34,9 +32,7 @@ func StartPostgresContainer(ctx context.Context) (*postgrescontainer.PostgresCon postgrescontainer.WithUsername(databaseUser), postgrescontainer.WithPassword(databasePassword), testcontainers.WithWaitStrategy( - wait.ForLog("database system is ready to accept connections"). - WithOccurrence(2).WithStartupTimeout(10*time.Second)), - ) + wait.ForLog("database system is ready to accept connections"))) if err != nil { return nil, nil, err } -- 2.45.1 From 429f68899dd373d8531288a6ae4e091d233b2c86 Mon Sep 17 00:00:00 2001 From: SoXX Date: Fri, 28 Jun 2024 10:43:55 +0200 Subject: [PATCH 108/124] feat(database): new fields Signed-off-by: SoXX --- internal/postgres/user.go | 13 ++++++-- pkg/database/database.go | 6 +++- .../migrations/001_inital_database.sql | 30 +++++++------------ pkg/database/postgres.go | 15 ++++++++++ pkg/models/const.go | 5 ++-- pkg/models/userSource.go | 19 +++++++----- 6 files changed, 54 insertions(+), 34 deletions(-) diff --git a/internal/postgres/user.go b/internal/postgres/user.go index d7b365a..b5c0ee3 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -6,6 +6,7 @@ import ( otterError "git.dragse.it/anthrove/otter-space-sdk/pkg/error" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + gonanoid "github.com/matoous/go-nanoid/v2" log "github.com/sirupsen/logrus" "gorm.io/gorm" ) @@ -56,15 +57,21 @@ func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUs return &otterError.EntityValidationFailed{Reason: "accountUsername cannot be empty"} } + validationCode, err := gonanoid.New(25) + + if err != nil { + return err + } + result := db.WithContext(ctx).Exec(`WITH userObj AS ( INSERT INTO "User" (id) VALUES ($1) ON CONFLICT (id) DO NOTHING ) - INSERT INTO "UserSource" (user_id, source_id, account_username, account_id) - SELECT $2, source.id, $3, $4 + INSERT INTO "UserSource" (user_id, source_id, account_username, account_id, account_validate, account_validation_key) + SELECT $2, source.id, $3, $4, false, $5 FROM "Source" AS source - WHERE source.id = $5;`, anthroveUserID, anthroveUserID, accountUsername, accountId, sourceID) + WHERE source.id = $6;`, anthroveUserID, anthroveUserID, accountUsername, accountId, validationCode, sourceID) if result.Error != nil { if errors.Is(result.Error, gorm.ErrDuplicatedKey) { diff --git a/pkg/database/database.go b/pkg/database/database.go index 3f739b4..691bd98 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -2,6 +2,7 @@ package database import ( "context" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" ) @@ -76,5 +77,8 @@ type OtterSpace interface { CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) DeleteTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName) error - UpdateUserWithScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error + UpdateUserSourceScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error + UpdateUserSourceLastScrapeTime(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, lastScrapeTime models.AnthroveUserLastScrapeTime) error + + UpdateUserSourceValidation(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, valid bool) error } diff --git a/pkg/database/migrations/001_inital_database.sql b/pkg/database/migrations/001_inital_database.sql index d580538..03932c9 100644 --- a/pkg/database/migrations/001_inital_database.sql +++ b/pkg/database/migrations/001_inital_database.sql @@ -27,7 +27,7 @@ CREATE TABLE "Post" CREATE TABLE "Source" ( - id CHAR(25) PRIMARY KEY, + id CHAR(25) PRIMARY KEY, display_name TEXT NULL, icon TEXT NULL, domain TEXT NOT NULL UNIQUE, @@ -89,11 +89,14 @@ CREATE TABLE "UserFavorites" CREATE TABLE "UserSource" ( - user_id TEXT REFERENCES "User" (id), - source_id TEXT REFERENCES "Source" (id), - scrape_time_interval TEXT, - account_username TEXT, - account_id TEXT, + user_id TEXT REFERENCES "User" (id), + source_id TEXT REFERENCES "Source" (id), + scrape_time_interval INT, + account_username TEXT, + account_id TEXT, + last_scrape_time TIMESTAMP, + account_validate BOOL DEFAULT FALSE, + account_validation_key CHAR(25), PRIMARY KEY (user_id, source_id), UNIQUE (source_id, account_username, account_id) ); @@ -103,17 +106,4 @@ CREATE TABLE "post_tags" post_id TEXT REFERENCES "Post" (id), tag_name TEXT REFERENCES "Tag" (name), PRIMARY KEY (post_id, tag_name) -); - --- +migrate Down -DROP TYPE Rating; -DROP TYPE TagType; -DROP TABLE Post; -DROP TABLE Source; -DROP TABLE Tag; -DROP TABLE User; -DROP TABLE PostReference; -DROP TABLE TagAlias; -DROP TABLE TagGroup; -DROP TABLE UserFavorites; -DROP TABLE UserSource; \ No newline at end of file +); \ No newline at end of file diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 1770610..fe078dc 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -193,6 +193,21 @@ func (p *postgresqlConnection) UpdateUserWithScrapeTimeInterval(ctx context.Cont panic("implement me") } +func (p *postgresqlConnection) UpdateUserSourceScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) UpdateUserSourceLastScrapeTime(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, lastScrapeTime models.AnthroveUserLastScrapeTime) error { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) UpdateUserSourceValidation(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, valid bool) error { + //TODO implement me + panic("implement me") +} + func (p *postgresqlConnection) migrateDatabase(dbPool *gorm.DB) error { dialect := "postgres" migrations := &migrate.EmbedFileSystemMigrationSource{FileSystem: embedMigrations, Root: "migrations"} diff --git a/pkg/models/const.go b/pkg/models/const.go index 13646fe..0e24228 100644 --- a/pkg/models/const.go +++ b/pkg/models/const.go @@ -1,7 +1,5 @@ package models -import "google.golang.org/genproto/googleapis/type/date" - type AnthroveUserID string type AnthrovePostID string type AnthroveSourceID string @@ -10,7 +8,8 @@ type AnthrovePostURL string type AnthroveTagGroupName string type AnthroveTagAliasName string type AnthroveTagID string -type AnthroveScrapeTimeInterval date.Date +type AnthroveScrapeTimeInterval int +type AnthroveUserLastScrapeTime int type Rating string type TagType string diff --git a/pkg/models/userSource.go b/pkg/models/userSource.go index 59788a1..8ac124e 100644 --- a/pkg/models/userSource.go +++ b/pkg/models/userSource.go @@ -1,13 +1,18 @@ package models +import "time" + type UserSource struct { - User User `gorm:"foreignKey:ID;references:UserID"` - UserID string `gorm:"primaryKey"` - Source Source `gorm:"foreignKey:ID;references:SourceID"` - SourceID string `gorm:"primaryKey"` - ScrapeTimeInterval string - AccountUsername string - AccountID string + User User `gorm:"foreignKey:ID;references:UserID"` + UserID string `gorm:"primaryKey"` + Source Source `gorm:"foreignKey:ID;references:SourceID"` + SourceID string `gorm:"primaryKey"` + ScrapeTimeInterval string + AccountUsername string + AccountID string + LastScrapeTime time.Time + AccountValidate bool + AccountValidationKey string } func (UserSource) TableName() string { -- 2.45.1 From bc8b5bb4a7a91517b9d505c8136eb06b2f346ab8 Mon Sep 17 00:00:00 2001 From: SoXX Date: Fri, 28 Jun 2024 10:54:42 +0200 Subject: [PATCH 109/124] refactor: reorganized code structure Signed-off-by: SoXX --- pkg/database/database.go | 72 ++------------------ pkg/database/post.go | 28 ++++++++ pkg/database/{ => postgres}/postgres.go | 5 +- pkg/database/{ => postgres}/postgres_test.go | 5 +- pkg/database/source.go | 19 ++++++ pkg/database/tag.go | 12 ++++ pkg/database/tagalias.go | 14 ++++ pkg/database/taggroup.go | 14 ++++ pkg/database/user.go | 29 ++++++++ pkg/database/usersource.go | 14 ++++ 10 files changed, 141 insertions(+), 71 deletions(-) create mode 100644 pkg/database/post.go rename pkg/database/{ => postgres}/postgres.go (98%) rename pkg/database/{ => postgres}/postgres_test.go (99%) create mode 100644 pkg/database/source.go create mode 100644 pkg/database/tag.go create mode 100644 pkg/database/tagalias.go create mode 100644 pkg/database/taggroup.go create mode 100644 pkg/database/user.go create mode 100644 pkg/database/usersource.go diff --git a/pkg/database/database.go b/pkg/database/database.go index 691bd98..c721eb4 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -10,75 +10,13 @@ type OtterSpace interface { // Connect establishes a connection to the database. Connect(ctx context.Context, config models.DatabaseConfig) error - // CreateUserWithRelationToSource adds a user with a relation to a source. - CreateUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, accountId string, accountUsername string) error + User - // CreateSource adds a new source to the database. - CreateSource(ctx context.Context, anthroveSource *models.Source) error + Source - // CreatePost adds a new post to the database. - CreatePost(ctx context.Context, anthrovePost *models.Post) error + TagAlias - // CreateTagAndReferenceToPost adds a tag with a relation to a post. - CreateTagAndReferenceToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error + TagGroup - // CreateReferenceBetweenPostAndSource links a post with a source. - CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL, config models.PostReferenceConfig) error - - // CreateReferenceBetweenUserAndPost links a user with a post. - CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error - - // CheckReferenceBetweenUserAndPost checks if a user-post link exists. - CheckReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID models.AnthrovePostID) (bool, error) - - // GetPostByAnthroveID retrieves a post by its Anthrove ID. - GetPostByAnthroveID(ctx context.Context, anthrovePostID models.AnthrovePostID) (*models.Post, error) - - // GetPostByURL retrieves a post by its source URL. - GetPostByURL(ctx context.Context, postURL string) (*models.Post, error) - - // GetPostBySourceID retrieves a post by its source ID. - GetPostBySourceID(ctx context.Context, sourceID models.AnthroveSourceID) (*models.Post, error) - - // GetUserFavoritesCount retrieves the count of a user's favorites. - GetUserFavoritesCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) - - // GetUserSourceLinks retrieves the source links of a user. - GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) - - // GetUserSourceBySourceID retrieves a specified source link of a user. - GetUserSourceBySourceID(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID) (map[string]models.UserSource, error) - - // GetAllAnthroveUserIDs retrieves all Anthrove user IDs. - GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) - - // GetUserFavoriteWithPagination retrieves a user's favorite posts with pagination. - GetUserFavoriteWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) - - // GetUserTagWitRelationToFavedPosts retrieves a user's tags through their favorited posts. - GetUserTagWitRelationToFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) - - // GetAllTags retrieves all tags. - GetAllTags(ctx context.Context) ([]models.Tag, error) - - // GetAllSources retrieves all sources. - GetAllSources(ctx context.Context) ([]models.Source, error) - - // GetSourceByDomain retrieves a source by its URL. - GetSourceByDomain(ctx context.Context, sourceDomain models.AnthroveSourceDomain) (*models.Source, error) - - GetAllTagAlias(ctx context.Context) ([]models.TagAlias, error) - GetAllTagAliasByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagAlias, error) - CreateTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName, tagID models.AnthroveTagID) error - DeleteTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName) error - - GetAllTagGroup(ctx context.Context) ([]models.TagGroup, error) - GetAllTagGroupByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagGroup, error) - CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) - DeleteTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName) error - - UpdateUserSourceScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error - UpdateUserSourceLastScrapeTime(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, lastScrapeTime models.AnthroveUserLastScrapeTime) error - - UpdateUserSourceValidation(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, valid bool) error + UserSource } diff --git a/pkg/database/post.go b/pkg/database/post.go new file mode 100644 index 0000000..7edb191 --- /dev/null +++ b/pkg/database/post.go @@ -0,0 +1,28 @@ +package database + +import ( + "context" + + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" +) + +type Post interface { + + // CreatePost adds a new post to the database. + CreatePost(ctx context.Context, anthrovePost *models.Post) error + + // GetPostByAnthroveID retrieves a post by its Anthrove ID. + GetPostByAnthroveID(ctx context.Context, anthrovePostID models.AnthrovePostID) (*models.Post, error) + + // GetPostByURL retrieves a post by its source URL. + GetPostByURL(ctx context.Context, postURL string) (*models.Post, error) + + // GetPostBySourceID retrieves a post by its source ID. + GetPostBySourceID(ctx context.Context, sourceID models.AnthroveSourceID) (*models.Post, error) + + // CreateTagAndReferenceToPost adds a tag with a relation to a post. + CreateTagAndReferenceToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error + + // CreateReferenceBetweenPostAndSource links a post with a source. + CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL, config models.PostReferenceConfig) error +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres/postgres.go similarity index 98% rename from pkg/database/postgres.go rename to pkg/database/postgres/postgres.go index fe078dc..714438a 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres/postgres.go @@ -1,4 +1,4 @@ -package database +package postgres import ( "context" @@ -9,6 +9,7 @@ import ( "time" "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" + "git.dragse.it/anthrove/otter-space-sdk/pkg/database" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" _ "github.com/lib/pq" migrate "github.com/rubenv/sql-migrate" @@ -26,7 +27,7 @@ type postgresqlConnection struct { debug bool } -func NewPostgresqlConnection() OtterSpace { +func NewPostgresqlConnection() database.OtterSpace { return &postgresqlConnection{ db: nil, } diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres/postgres_test.go similarity index 99% rename from pkg/database/postgres_test.go rename to pkg/database/postgres/postgres_test.go index c7d4996..721752a 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres/postgres_test.go @@ -1,4 +1,4 @@ -package database +package postgres import ( "context" @@ -7,6 +7,7 @@ import ( "testing" "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" + "git.dragse.it/anthrove/otter-space-sdk/pkg/database" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/test" "gorm.io/gorm" @@ -16,7 +17,7 @@ func TestNewPostgresqlConnection(t *testing.T) { // Test tests := []struct { name string - want OtterSpace + want database.OtterSpace }{ { name: "Test 1: Create new postgresql connection", diff --git a/pkg/database/source.go b/pkg/database/source.go new file mode 100644 index 0000000..776c1d1 --- /dev/null +++ b/pkg/database/source.go @@ -0,0 +1,19 @@ +package database + +import ( + "context" + + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" +) + +type Source interface { + + // CreateSource adds a new source to the database. + CreateSource(ctx context.Context, anthroveSource *models.Source) error + + // GetAllSources retrieves all sources. + GetAllSources(ctx context.Context) ([]models.Source, error) + + // GetSourceByDomain retrieves a source by its URL. + GetSourceByDomain(ctx context.Context, sourceDomain models.AnthroveSourceDomain) (*models.Source, error) +} diff --git a/pkg/database/tag.go b/pkg/database/tag.go new file mode 100644 index 0000000..eb0f4a5 --- /dev/null +++ b/pkg/database/tag.go @@ -0,0 +1,12 @@ +package database + +import ( + "context" + + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" +) + +type Tag interface { + // GetAllTags retrieves all tags. + GetAllTags(ctx context.Context) ([]models.Tag, error) +} diff --git a/pkg/database/tagalias.go b/pkg/database/tagalias.go new file mode 100644 index 0000000..ef5f2e5 --- /dev/null +++ b/pkg/database/tagalias.go @@ -0,0 +1,14 @@ +package database + +import ( + "context" + + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" +) + +type TagAlias interface { + GetAllTagAlias(ctx context.Context) ([]models.TagAlias, error) + GetAllTagAliasByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagAlias, error) + CreateTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName, tagID models.AnthroveTagID) error + DeleteTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName) error +} diff --git a/pkg/database/taggroup.go b/pkg/database/taggroup.go new file mode 100644 index 0000000..db3918a --- /dev/null +++ b/pkg/database/taggroup.go @@ -0,0 +1,14 @@ +package database + +import ( + "context" + + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" +) + +type TagGroup interface { + GetAllTagGroup(ctx context.Context) ([]models.TagGroup, error) + GetAllTagGroupByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagGroup, error) + CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) + DeleteTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName) error +} diff --git a/pkg/database/user.go b/pkg/database/user.go new file mode 100644 index 0000000..1b72e61 --- /dev/null +++ b/pkg/database/user.go @@ -0,0 +1,29 @@ +package database + +import ( + "context" + + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" +) + +type User interface { + // GetAllAnthroveUserIDs retrieves all Anthrove user IDs. + GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) + + // CreateUserWithRelationToSource adds a user with a relation to a source. + CreateUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, accountId string, accountUsername string) error + // CreateReferenceBetweenUserAndPost links a user with a post. + CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error + // CheckReferenceBetweenUserAndPost checks if a user-post link exists. + CheckReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID models.AnthrovePostID) (bool, error) + // GetUserFavoritesCount retrieves the count of a user's favorites. + GetUserFavoritesCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) + // GetUserSourceLinks retrieves the source links of a user. + GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) + // GetUserSourceBySourceID retrieves a specified source link of a user. + GetUserSourceBySourceID(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID) (map[string]models.UserSource, error) + // GetUserFavoriteWithPagination retrieves a user's favorite posts with pagination. + GetUserFavoriteWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) + // GetUserTagWitRelationToFavedPosts retrieves a user's tags through their favorited posts. + GetUserTagWitRelationToFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) +} diff --git a/pkg/database/usersource.go b/pkg/database/usersource.go new file mode 100644 index 0000000..1f30a48 --- /dev/null +++ b/pkg/database/usersource.go @@ -0,0 +1,14 @@ +package database + +import ( + "context" + + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" +) + +type UserSource interface { + UpdateUserSourceScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error + UpdateUserSourceLastScrapeTime(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, lastScrapeTime models.AnthroveUserLastScrapeTime) error + + UpdateUserSourceValidation(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, valid bool) error +} -- 2.45.1 From 5de00e6861a438ef8a116b72f3ae7fb2f740120b Mon Sep 17 00:00:00 2001 From: SoXX Date: Fri, 28 Jun 2024 10:58:07 +0200 Subject: [PATCH 110/124] refactor: reorganized code structure Signed-off-by: SoXX --- pkg/database/database.go | 5 ----- pkg/database/user.go | 5 +++++ pkg/database/usersource.go | 14 -------------- 3 files changed, 5 insertions(+), 19 deletions(-) delete mode 100644 pkg/database/usersource.go diff --git a/pkg/database/database.go b/pkg/database/database.go index c721eb4..0cd0777 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -11,12 +11,7 @@ type OtterSpace interface { Connect(ctx context.Context, config models.DatabaseConfig) error User - Source - TagAlias - TagGroup - - UserSource } diff --git a/pkg/database/user.go b/pkg/database/user.go index 1b72e61..d90ca51 100644 --- a/pkg/database/user.go +++ b/pkg/database/user.go @@ -26,4 +26,9 @@ type User interface { GetUserFavoriteWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) // GetUserTagWitRelationToFavedPosts retrieves a user's tags through their favorited posts. GetUserTagWitRelationToFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) + + UpdateUserSourceScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error + UpdateUserSourceLastScrapeTime(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, lastScrapeTime models.AnthroveUserLastScrapeTime) error + + UpdateUserSourceValidation(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, valid bool) error } diff --git a/pkg/database/usersource.go b/pkg/database/usersource.go deleted file mode 100644 index 1f30a48..0000000 --- a/pkg/database/usersource.go +++ /dev/null @@ -1,14 +0,0 @@ -package database - -import ( - "context" - - "git.dragse.it/anthrove/otter-space-sdk/pkg/models" -) - -type UserSource interface { - UpdateUserSourceScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error - UpdateUserSourceLastScrapeTime(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, lastScrapeTime models.AnthroveUserLastScrapeTime) error - - UpdateUserSourceValidation(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, valid bool) error -} -- 2.45.1 From 4a0b7d71a9a5ccbfb88af29ad161c988d58cb429 Mon Sep 17 00:00:00 2001 From: SoXX Date: Fri, 28 Jun 2024 12:15:51 +0200 Subject: [PATCH 111/124] refactor: reorganized code structure Signed-off-by: SoXX --- internal/postgres/relationships_test.go | 8 ++--- internal/postgres/user.go | 41 +++++-------------------- internal/postgres/user_test.go | 18 +++++------ pkg/database/database.go | 7 +++++ pkg/database/postgres/postgres.go | 14 ++++----- pkg/database/postgres/postgres_test.go | 28 ++++++++--------- pkg/database/tagalias.go | 7 +++-- pkg/database/taggroup.go | 7 +++-- pkg/database/user.go | 36 +++++++++++++--------- test/helper.go | 17 +++++----- 10 files changed, 89 insertions(+), 94 deletions(-) diff --git a/internal/postgres/relationships_test.go b/internal/postgres/relationships_test.go index dec686d..dd67e2a 100644 --- a/internal/postgres/relationships_test.go +++ b/internal/postgres/relationships_test.go @@ -133,11 +133,11 @@ func TestCheckUserToPostLink(t *testing.T) { t.Run(tt.name, func(t *testing.T) { got, err := CheckReferenceBetweenUserAndPost(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.anthrovePostID) if (err != nil) != tt.wantErr { - t.Errorf("CheckReferenceBetweenUserAndPost() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("CheckIfUserHasPostAsFavorite() error = %v, wantErr %v", err, tt.wantErr) return } if got != tt.want { - t.Errorf("CheckReferenceBetweenUserAndPost() got = %v, want %v", got, tt.want) + t.Errorf("CheckIfUserHasPostAsFavorite() got = %v, want %v", got, tt.want) } }) } @@ -266,11 +266,11 @@ func TestCheckUserToPostLinkWithNoData(t *testing.T) { t.Run(tt.name, func(t *testing.T) { got, err := CheckReferenceBetweenUserAndPost(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.anthrovePostID) if (err != nil) != tt.wantErr { - t.Errorf("CheckReferenceBetweenUserAndPost() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("CheckIfUserHasPostAsFavorite() error = %v, wantErr %v", err, tt.wantErr) return } if got != tt.want { - t.Errorf("CheckReferenceBetweenUserAndPost() got = %v, want %v", got, tt.want) + t.Errorf("CheckIfUserHasPostAsFavorite() got = %v, want %v", got, tt.want) } }) } diff --git a/internal/postgres/user.go b/internal/postgres/user.go index b5c0ee3..8e8b2d7 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -169,9 +169,8 @@ func GetUserSourceLinks(ctx context.Context, db *gorm.DB, anthroveUserID models. return userSourceMap, nil } -func GetUserSourceBySourceID(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID) (map[string]models.UserSource, error) { - var userSources []models.UserSource - userSourceMap := make(map[string]models.UserSource) +func GetUserSourceBySourceID(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID) (*models.UserSource, error) { + var userSource *models.UserSource if anthroveUserID == "" { return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} @@ -189,7 +188,7 @@ func GetUserSourceBySourceID(ctx context.Context, db *gorm.DB, anthroveUserID mo return nil, &otterError.EntityValidationFailed{Reason: "sourceID needs to be 25 characters long"} } - result := db.WithContext(ctx).Model(&models.UserSource{}).InnerJoins("Source", db.Where("id = ?", sourceID)).Where("user_id = ?", string(anthroveUserID)).First(&userSources) + result := db.WithContext(ctx).Model(&models.UserSource{}).InnerJoins("Source", db.Where("id = ?", sourceID)).Where("user_id = ?", string(anthroveUserID)).First(userSource) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { return nil, &otterError.NoDataFound{} @@ -197,38 +196,16 @@ func GetUserSourceBySourceID(ctx context.Context, db *gorm.DB, anthroveUserID mo return nil, result.Error } - for _, userSource := range userSources { - var source models.Source - result = db.WithContext(ctx).Model(&models.Source{}).Where("id = ?", userSource.SourceID).First(&source) - if result.Error != nil { - if errors.Is(result.Error, gorm.ErrRecordNotFound) { - return nil, &otterError.NoDataFound{} - } - return nil, result.Error - } - - userSourceMap[source.DisplayName] = models.UserSource{ - UserID: userSource.AccountID, - AccountUsername: userSource.AccountUsername, - Source: models.Source{ - DisplayName: source.DisplayName, - Domain: source.Domain, - Icon: source.Icon, - }, - } - } - log.WithFields(log.Fields{ "anthrove_user_id": anthroveUserID, "source_id": sourceID, }).Trace("database: got specified user source link") - return userSourceMap, nil + return userSource, nil } -func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveUserID, error) { +func GetAllUsers(ctx context.Context, db *gorm.DB) ([]models.User, error) { var users []models.User - var userIDs []models.AnthroveUserID result := db.WithContext(ctx).Model(&models.User{}).Find(&users) if result.Error != nil { @@ -238,15 +215,11 @@ func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveU return nil, result.Error } - for _, user := range users { - userIDs = append(userIDs, user.ID) - } - log.WithFields(log.Fields{ - "anthrove_user_id_count": len(userIDs), + "anthrove_user_id_count": len(users), }).Trace("database: got all anthrove user IDs") - return userIDs, nil + return users, nil } func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) { diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index b146d52..c4efa00 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -244,13 +244,13 @@ func TestGetAllAnthroveUserIDs(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := GetAllAnthroveUserIDs(tt.args.ctx, tt.args.db) + got, err := GetAllUsers(tt.args.ctx, tt.args.db) if (err != nil) != tt.wantErr { - t.Errorf("GetAllAnthroveUserIDs() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetAllUsers() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetAllAnthroveUserIDs() got = %v, want %v", got, tt.want) + t.Errorf("GetAllUsers() got = %v, want %v", got, tt.want) } }) } @@ -558,11 +558,11 @@ func TestGetUserFavoriteNodeWithPagination(t *testing.T) { t.Run(tt.name, func(t *testing.T) { got, err := GetUserFavoriteWithPagination(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.skip, tt.args.limit) if (err != nil) != tt.wantErr { - t.Errorf("GetUserFavoriteWithPagination() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetAllUserFavoritesWithPagination() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetUserFavoriteWithPagination() got = %v, want %v", got, tt.want) + t.Errorf("GetAllUserFavoritesWithPagination() got = %v, want %v", got, tt.want) } }) } @@ -798,11 +798,11 @@ func TestGetUserSourceLinks(t *testing.T) { t.Run(tt.name, func(t *testing.T) { got, err := GetUserSourceLinks(tt.args.ctx, tt.args.db, tt.args.anthroveUserID) if (err != nil) != tt.wantErr { - t.Errorf("GetUserSourceLinks() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetAllUserSources() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetUserSourceLinks() got = %v, want %v", got, tt.want) + t.Errorf("GetAllUserSources() got = %v, want %v", got, tt.want) } }) } @@ -930,11 +930,11 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { t.Run(tt.name, func(t *testing.T) { got, err := GetUserTagWitRelationToFavedPosts(tt.args.ctx, tt.args.db, tt.args.anthroveUserID) if (err != nil) != tt.wantErr { - t.Errorf("GetUserTagWitRelationToFavedPosts() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetAllTagsFromUser() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetUserTagWitRelationToFavedPosts() got = %v, want %v", got, tt.want) + t.Errorf("GetAllTagsFromUser() got = %v, want %v", got, tt.want) } }) } diff --git a/pkg/database/database.go b/pkg/database/database.go index 0cd0777..7b1aef2 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -10,8 +10,15 @@ type OtterSpace interface { // Connect establishes a connection to the database. Connect(ctx context.Context, config models.DatabaseConfig) error + // User contains all function that are needed to manage the AnthroveUser User + + // Source contains all function that are needed to manage the Source Source + + // TagAlias contains all function that are needed to manage the TagAlias TagAlias + + // TagGroup contains all function that are needed to manage the TagGroup TagGroup } diff --git a/pkg/database/postgres/postgres.go b/pkg/database/postgres/postgres.go index 714438a..da69ba8 100644 --- a/pkg/database/postgres/postgres.go +++ b/pkg/database/postgres/postgres.go @@ -97,7 +97,7 @@ func (p *postgresqlConnection) CreateReferenceBetweenUserAndPost(ctx context.Con return postgres.CreateReferenceBetweenUserAndPost(ctx, p.db, anthroveUserID, anthrovePostID) } -func (p *postgresqlConnection) CheckReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) (bool, error) { +func (p *postgresqlConnection) CheckIfUserHasPostAsFavorite(ctx context.Context, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) (bool, error) { return postgres.CheckReferenceBetweenUserAndPost(ctx, p.db, anthroveUserID, anthrovePostID) } @@ -117,23 +117,23 @@ func (p *postgresqlConnection) GetUserFavoritesCount(ctx context.Context, anthro return postgres.GetUserFavoritesCount(ctx, p.db, anthroveUserID) } -func (p *postgresqlConnection) GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) { +func (p *postgresqlConnection) GetAllUserSources(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) { return postgres.GetUserSourceLinks(ctx, p.db, anthroveUserID) } -func (p *postgresqlConnection) GetUserSourceBySourceID(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID) (map[string]models.UserSource, error) { +func (p *postgresqlConnection) GetUserSourceBySourceID(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID) (*models.UserSource, error) { return postgres.GetUserSourceBySourceID(ctx, p.db, anthroveUserID, sourceID) } -func (p *postgresqlConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) { - return postgres.GetAllAnthroveUserIDs(ctx, p.db) +func (p *postgresqlConnection) GetAllUser(ctx context.Context) ([]models.User, error) { + return postgres.GetAllUsers(ctx, p.db) } -func (p *postgresqlConnection) GetUserFavoriteWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) { +func (p *postgresqlConnection) GetAllUserFavoritesWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) { return postgres.GetUserFavoriteWithPagination(ctx, p.db, anthroveUserID, skip, limit) } -func (p *postgresqlConnection) GetUserTagWitRelationToFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { +func (p *postgresqlConnection) GetAllTagsFromUser(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { return postgres.GetUserTagWitRelationToFavedPosts(ctx, p.db, anthroveUserID) } diff --git a/pkg/database/postgres/postgres_test.go b/pkg/database/postgres/postgres_test.go index 721752a..bf7159f 100644 --- a/pkg/database/postgres/postgres_test.go +++ b/pkg/database/postgres/postgres_test.go @@ -714,13 +714,13 @@ func Test_postgresqlConnection_CheckReferenceBetweenUserAndPost(t *testing.T) { db: gormDB, debug: true, } - got, err := p.CheckReferenceBetweenUserAndPost(tt.args.ctx, tt.args.anthroveUserID, tt.args.anthrovePostID) + got, err := p.CheckIfUserFavouritedPost(tt.args.ctx, tt.args.anthroveUserID, tt.args.anthrovePostID) if (err != nil) != tt.wantErr { - t.Errorf("CheckReferenceBetweenUserAndPost() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("CheckIfUserHasPostAsFavorite() error = %v, wantErr %v", err, tt.wantErr) return } if got != tt.want { - t.Errorf("CheckReferenceBetweenUserAndPost() got = %v, want %v", got, tt.want) + t.Errorf("CheckIfUserHasPostAsFavorite() got = %v, want %v", got, tt.want) } }) } @@ -1207,13 +1207,13 @@ func Test_postgresqlConnection_GetUserSourceLinks(t *testing.T) { db: gormDB, debug: true, } - got, err := p.GetUserSourceLinks(tt.args.ctx, tt.args.anthroveUserID) + got, err := p.GetAllUserSources(tt.args.ctx, tt.args.anthroveUserID) if (err != nil) != tt.wantErr { - t.Errorf("GetUserSourceLinks() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetAllUserSources() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetUserSourceLinks() got = %v, want %v", got, tt.want) + t.Errorf("GetAllUserSources() got = %v, want %v", got, tt.want) } }) } @@ -1405,11 +1405,11 @@ func Test_postgresqlConnection_GetAllAnthroveUserIDs(t *testing.T) { } got, err := p.GetAllAnthroveUserIDs(tt.args.ctx) if (err != nil) != tt.wantErr { - t.Errorf("GetAllAnthroveUserIDs() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetAllUsers() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetAllAnthroveUserIDs() got = %v, want %v", got, tt.want) + t.Errorf("GetAllUsers() got = %v, want %v", got, tt.want) } }) } @@ -1540,13 +1540,13 @@ func Test_postgresqlConnection_GetUserFavoriteWithPagination(t *testing.T) { db: gormDB, debug: true, } - got, err := p.GetUserFavoriteWithPagination(tt.args.ctx, tt.args.anthroveUserID, tt.args.skip, tt.args.limit) + got, err := p.GetAllUserFavoritesWithPagination(tt.args.ctx, tt.args.anthroveUserID, tt.args.skip, tt.args.limit) if (err != nil) != tt.wantErr { - t.Errorf("GetUserFavoriteWithPagination() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetAllUserFavoritesWithPagination() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetUserFavoriteWithPagination() got = %v, want %v", got, tt.want) + t.Errorf("GetAllUserFavoritesWithPagination() got = %v, want %v", got, tt.want) } }) } @@ -1654,13 +1654,13 @@ func Test_postgresqlConnection_GetUserTagWitRelationToFavedPosts(t *testing.T) { db: gormDB, debug: true, } - got, err := p.GetUserTagWitRelationToFavedPosts(tt.args.ctx, tt.args.anthroveUserID) + got, err := p.GetAllTagsFromUser(tt.args.ctx, tt.args.anthroveUserID) if (err != nil) != tt.wantErr { - t.Errorf("GetUserTagWitRelationToFavedPosts() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetAllTagsFromUser() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("GetUserTagWitRelationToFavedPosts() got = %v, want %v", got, tt.want) + t.Errorf("GetAllTagsFromUser() got = %v, want %v", got, tt.want) } }) } diff --git a/pkg/database/tagalias.go b/pkg/database/tagalias.go index ef5f2e5..30171d4 100644 --- a/pkg/database/tagalias.go +++ b/pkg/database/tagalias.go @@ -7,8 +7,11 @@ import ( ) type TagAlias interface { - GetAllTagAlias(ctx context.Context) ([]models.TagAlias, error) - GetAllTagAliasByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagAlias, error) CreateTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName, tagID models.AnthroveTagID) error + + GetAllTagAlias(ctx context.Context) ([]models.TagAlias, error) + + GetAllTagAliasByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagAlias, error) + DeleteTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName) error } diff --git a/pkg/database/taggroup.go b/pkg/database/taggroup.go index db3918a..594cd1e 100644 --- a/pkg/database/taggroup.go +++ b/pkg/database/taggroup.go @@ -7,8 +7,11 @@ import ( ) type TagGroup interface { - GetAllTagGroup(ctx context.Context) ([]models.TagGroup, error) - GetAllTagGroupByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagGroup, error) CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) + + GetAllTagGroup(ctx context.Context) ([]models.TagGroup, error) + + GetAllTagGroupByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagGroup, error) + DeleteTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName) error } diff --git a/pkg/database/user.go b/pkg/database/user.go index d90ca51..e7be12e 100644 --- a/pkg/database/user.go +++ b/pkg/database/user.go @@ -7,28 +7,36 @@ import ( ) type User interface { - // GetAllAnthroveUserIDs retrieves all Anthrove user IDs. - GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) // CreateUserWithRelationToSource adds a user with a relation to a source. CreateUserWithRelationToSource(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, accountId string, accountUsername string) error + // CreateReferenceBetweenUserAndPost links a user with a post. CreateReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error - // CheckReferenceBetweenUserAndPost checks if a user-post link exists. - CheckReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID models.AnthrovePostID) (bool, error) - // GetUserFavoritesCount retrieves the count of a user's favorites. - GetUserFavoritesCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) - // GetUserSourceLinks retrieves the source links of a user. - GetUserSourceLinks(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) - // GetUserSourceBySourceID retrieves a specified source link of a user. - GetUserSourceBySourceID(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID) (map[string]models.UserSource, error) - // GetUserFavoriteWithPagination retrieves a user's favorite posts with pagination. - GetUserFavoriteWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) - // GetUserTagWitRelationToFavedPosts retrieves a user's tags through their favorited posts. - GetUserTagWitRelationToFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) UpdateUserSourceScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error + UpdateUserSourceLastScrapeTime(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, lastScrapeTime models.AnthroveUserLastScrapeTime) error UpdateUserSourceValidation(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, valid bool) error + + GetAllUser(ctx context.Context) ([]models.User, error) + + // GetUserFavoritesCount retrieves the count of a user's favorites. + GetUserFavoritesCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) + + // GetAllUserSources retrieves the source links of a user. + GetAllUserSources(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) + + // GetUserSourceBySourceID retrieves a specified source link of a user. + GetUserSourceBySourceID(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID) (*models.UserSource, error) + + // GetAllUserFavoritesWithPagination retrieves a user's favorite posts with pagination. + GetAllUserFavoritesWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) + + // GetAllTagsFromUser retrieves a user's tags through their favorite posts. + GetAllTagsFromUser(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) + + // CheckIfUserHasPostAsFavorite checks if a user-post link exists. + CheckIfUserHasPostAsFavorite(ctx context.Context, anthroveUserID models.AnthroveUserID, sourcePostID models.AnthrovePostID) (bool, error) } diff --git a/test/helper.go b/test/helper.go index 93a185e..ce571d2 100644 --- a/test/helper.go +++ b/test/helper.go @@ -3,15 +3,16 @@ package test import ( "context" "database/sql" + "net/url" + "strconv" + "strings" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" migrate "github.com/rubenv/sql-migrate" postgrescontainer "github.com/testcontainers/testcontainers-go/modules/postgres" "gorm.io/driver/postgres" "gorm.io/gorm" "gorm.io/gorm/logger" - "net/url" - "strconv" - "strings" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" @@ -88,12 +89,12 @@ func DatabaseModesFromConnectionString(ctx context.Context, pgContainer *postgre return nil, err } - url, err := url.Parse(connectionString) + connectionStringUrl, err := url.Parse(connectionString) if err != nil { return nil, err } - split := strings.Split(url.Host, ":") + split := strings.Split(connectionStringUrl.Host, ":") host := split[0] port, err := strconv.Atoi(split[1]) @@ -101,10 +102,10 @@ func DatabaseModesFromConnectionString(ctx context.Context, pgContainer *postgre return nil, err } - database := strings.TrimPrefix(url.Path, "/") + database := strings.TrimPrefix(connectionStringUrl.Path, "/") - username := url.User.Username() - password, _ := url.User.Password() + username := connectionStringUrl.User.Username() + password, _ := connectionStringUrl.User.Password() return &models.DatabaseConfig{ Endpoint: host, -- 2.45.1 From b5437ecc6298c3da5d807f3082ac784d8000ddc0 Mon Sep 17 00:00:00 2001 From: SoXX Date: Fri, 28 Jun 2024 14:16:28 +0200 Subject: [PATCH 112/124] tests: fixed tests Signed-off-by: SoXX --- internal/postgres/tag_test.go | 2 +- internal/postgres/user.go | 6 +- internal/postgres/user_test.go | 69 +++++++++++++--- pkg/database/database.go | 3 + pkg/database/post.go | 8 +- pkg/database/{postgres => }/postgres.go | 11 ++- pkg/database/{postgres => }/postgres_test.go | 87 +++++++++++++++----- pkg/database/user.go | 2 +- pkg/models/postReference_test.go | 16 ++-- test/helper.go | 7 +- 10 files changed, 155 insertions(+), 56 deletions(-) rename pkg/database/{postgres => }/postgres.go (93%) rename pkg/database/{postgres => }/postgres_test.go (95%) diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index 045cd96..3f22c76 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -94,7 +94,7 @@ func TestCreateTagNodeWitRelation(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := CreateTagAndReferenceToPost(tt.args.ctx, tt.args.db, tt.args.PostID, tt.args.tag); (err != nil) != tt.wantErr { - t.Errorf("CreateTagAndReferenceToPost() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("CreatePostWithReferenceToTagAnd() error = %v, wantErr %v", err, tt.wantErr) } }) } diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 8e8b2d7..c0a2543 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -170,7 +170,7 @@ func GetUserSourceLinks(ctx context.Context, db *gorm.DB, anthroveUserID models. } func GetUserSourceBySourceID(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID) (*models.UserSource, error) { - var userSource *models.UserSource + var userSource models.UserSource if anthroveUserID == "" { return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} @@ -188,7 +188,7 @@ func GetUserSourceBySourceID(ctx context.Context, db *gorm.DB, anthroveUserID mo return nil, &otterError.EntityValidationFailed{Reason: "sourceID needs to be 25 characters long"} } - result := db.WithContext(ctx).Model(&models.UserSource{}).InnerJoins("Source", db.Where("id = ?", sourceID)).Where("user_id = ?", string(anthroveUserID)).First(userSource) + result := db.WithContext(ctx).Model(&models.UserSource{}).InnerJoins("Source", db.Where("id = ?", sourceID)).Where("user_id = ?", string(anthroveUserID)).First(&userSource) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { return nil, &otterError.NoDataFound{} @@ -201,7 +201,7 @@ func GetUserSourceBySourceID(ctx context.Context, db *gorm.DB, anthroveUserID mo "source_id": sourceID, }).Trace("database: got specified user source link") - return userSource, nil + return &userSource, nil } func GetAllUsers(ctx context.Context, db *gorm.DB) ([]models.User, error) { diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index c4efa00..8dfa13a 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -198,7 +198,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) { } } -func TestGetAllAnthroveUserIDs(t *testing.T) { +func TestGetAllUsers(t *testing.T) { // Setup trow away container ctx := context.Background() container, gormDB, err := test.StartPostgresContainer(ctx) @@ -212,10 +212,20 @@ func TestGetAllAnthroveUserIDs(t *testing.T) { validUserID02 := models.AnthroveUserID(fmt.Sprintf("%025s", "User2")) validUserID03 := models.AnthroveUserID(fmt.Sprintf("%025s", "User3")) - users := []models.AnthroveUserID{validUserID01, validUserID02, validUserID03} + users := []models.User{ + { + BaseModel: models.BaseModel[models.AnthroveUserID]{ID: validUserID01}, + }, + { + BaseModel: models.BaseModel[models.AnthroveUserID]{ID: validUserID02}, + }, + { + BaseModel: models.BaseModel[models.AnthroveUserID]{ID: validUserID03}, + }, + } for _, user := range users { - err = CreateUser(ctx, gormDB, user) + err = CreateUser(ctx, gormDB, user.ID) if err != nil { t.Fatal(err) } @@ -229,7 +239,7 @@ func TestGetAllAnthroveUserIDs(t *testing.T) { tests := []struct { name string args args - want []models.AnthroveUserID + want []models.User wantErr bool }{ { @@ -249,7 +259,7 @@ func TestGetAllAnthroveUserIDs(t *testing.T) { t.Errorf("GetAllUsers() error = %v, wantErr %v", err, tt.wantErr) return } - if !reflect.DeepEqual(got, tt.want) { + if !checkUser(got, tt.want) { t.Errorf("GetAllUsers() got = %v, want %v", got, tt.want) } }) @@ -278,13 +288,14 @@ func TestGetUserSourceBySourceID(t *testing.T) { }, DisplayName: "e621", Domain: "e621.net", + Icon: "https://e621.icon", } - expectedResult := make(map[string]models.UserSource) - expectedResult["e621"] = models.UserSource{ - UserID: "e1", + expectedResult := &models.UserSource{ + UserID: string(validUserID), AccountUsername: "euser", Source: models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: source.ID}, DisplayName: source.DisplayName, Domain: source.Domain, Icon: source.Icon, @@ -296,7 +307,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { t.Fatal(err) } - err = CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) + err = CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, expectedResult.UserID, expectedResult.AccountUsername) if err != nil { t.Fatal(err) } @@ -311,7 +322,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { tests := []struct { name string args args - want map[string]models.UserSource + want *models.UserSource wantErr bool }{ { @@ -400,7 +411,7 @@ func TestGetUserSourceBySourceID(t *testing.T) { t.Errorf("GetUserSourceBySourceID() error = %v, wantErr %v", err, tt.wantErr) return } - if !reflect.DeepEqual(got, tt.want) { + if !checkUserSource(got, tt.want) { t.Errorf("GetUserSourceBySourceID() got = %v, want %v", got, tt.want) } }) @@ -939,3 +950,39 @@ func TestGetUserTagNodeWitRelationToFavedPosts(t *testing.T) { }) } } + +func checkUser(got []models.User, want []models.User) bool { + for i, user := range want { + if user.ID != got[i].ID { + return false + } + } + return true +} + +func checkUserSource(got *models.UserSource, want *models.UserSource) bool { + + if got == nil && want == nil { + return true + } else if got == nil || want == nil { + return false + } + + if got.UserID != want.UserID { + return false + } + if got.AccountUsername != want.AccountUsername { + return false + } + if got.Source.DisplayName != want.Source.DisplayName { + return false + } + if got.Source.Domain != want.Source.Domain { + return false + } + if got.Source.Icon != want.Source.Icon { + return false + } + + return true +} diff --git a/pkg/database/database.go b/pkg/database/database.go index 7b1aef2..0bce2bf 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -10,6 +10,9 @@ type OtterSpace interface { // Connect establishes a connection to the database. Connect(ctx context.Context, config models.DatabaseConfig) error + // Post contains all function that are needed to manage Posts + Post + // User contains all function that are needed to manage the AnthroveUser User diff --git a/pkg/database/post.go b/pkg/database/post.go index 7edb191..0111170 100644 --- a/pkg/database/post.go +++ b/pkg/database/post.go @@ -20,9 +20,9 @@ type Post interface { // GetPostBySourceID retrieves a post by its source ID. GetPostBySourceID(ctx context.Context, sourceID models.AnthroveSourceID) (*models.Post, error) - // CreateTagAndReferenceToPost adds a tag with a relation to a post. - CreateTagAndReferenceToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error + // CreatePostWithReferenceToTagAnd adds a tag with a relation to a post. + CreatePostWithReferenceToTagAnd(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error - // CreateReferenceBetweenPostAndSource links a post with a source. - CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL, config models.PostReferenceConfig) error + // CreatePostReference links a post with a source. + CreatePostReference(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL, config models.PostReferenceConfig) error } diff --git a/pkg/database/postgres/postgres.go b/pkg/database/postgres.go similarity index 93% rename from pkg/database/postgres/postgres.go rename to pkg/database/postgres.go index da69ba8..b63ca0b 100644 --- a/pkg/database/postgres/postgres.go +++ b/pkg/database/postgres.go @@ -1,4 +1,4 @@ -package postgres +package database import ( "context" @@ -9,7 +9,6 @@ import ( "time" "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" - "git.dragse.it/anthrove/otter-space-sdk/pkg/database" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" _ "github.com/lib/pq" migrate "github.com/rubenv/sql-migrate" @@ -27,7 +26,7 @@ type postgresqlConnection struct { debug bool } -func NewPostgresqlConnection() database.OtterSpace { +func NewPostgresqlConnection() OtterSpace { return &postgresqlConnection{ db: nil, } @@ -85,11 +84,11 @@ func (p *postgresqlConnection) CreatePost(ctx context.Context, anthrovePost *mod return postgres.CreatePost(ctx, p.db, anthrovePost) } -func (p *postgresqlConnection) CreateTagAndReferenceToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error { +func (p *postgresqlConnection) CreatePostWithReferenceToTagAnd(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error { return postgres.CreateTagAndReferenceToPost(ctx, p.db, anthrovePostID, anthroveTag) } -func (p *postgresqlConnection) CreateReferenceBetweenPostAndSource(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL, config models.PostReferenceConfig) error { +func (p *postgresqlConnection) CreatePostReference(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL, config models.PostReferenceConfig) error { return postgres.CreateReferenceBetweenPostAndSource(ctx, p.db, anthrovePostID, sourceDomain, postURL, config) } @@ -125,7 +124,7 @@ func (p *postgresqlConnection) GetUserSourceBySourceID(ctx context.Context, anth return postgres.GetUserSourceBySourceID(ctx, p.db, anthroveUserID, sourceID) } -func (p *postgresqlConnection) GetAllUser(ctx context.Context) ([]models.User, error) { +func (p *postgresqlConnection) GetAllUsers(ctx context.Context) ([]models.User, error) { return postgres.GetAllUsers(ctx, p.db) } diff --git a/pkg/database/postgres/postgres_test.go b/pkg/database/postgres_test.go similarity index 95% rename from pkg/database/postgres/postgres_test.go rename to pkg/database/postgres_test.go index bf7159f..26a46fb 100644 --- a/pkg/database/postgres/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -1,4 +1,4 @@ -package postgres +package database import ( "context" @@ -7,7 +7,6 @@ import ( "testing" "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" - "git.dragse.it/anthrove/otter-space-sdk/pkg/database" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/test" "gorm.io/gorm" @@ -17,7 +16,7 @@ func TestNewPostgresqlConnection(t *testing.T) { // Test tests := []struct { name string - want database.OtterSpace + want OtterSpace }{ { name: "Test 1: Create new postgresql connection", @@ -421,8 +420,8 @@ func Test_postgresqlConnection_CreateTagAndReferenceToPost(t *testing.T) { db: gormDB, debug: true, } - if err := p.CreateTagAndReferenceToPost(tt.args.ctx, tt.args.anthrovePostID, tt.args.anthroveTag); (err != nil) != tt.wantErr { - t.Errorf("CreateTagAndReferenceToPost() error = %v, wantErr %v", err, tt.wantErr) + if err := p.CreatePostWithReferenceToTagAnd(tt.args.ctx, tt.args.anthrovePostID, tt.args.anthroveTag); (err != nil) != tt.wantErr { + t.Errorf("CreatePostWithReferenceToTagAnd() error = %v, wantErr %v", err, tt.wantErr) } }) } @@ -522,8 +521,8 @@ func Test_postgresqlConnection_CreateReferenceBetweenPostAndSource(t *testing.T) db: gormDB, debug: true, } - if err := p.CreateReferenceBetweenPostAndSource(tt.args.ctx, tt.args.anthrovePostID, tt.args.sourceDomain, tt.args.postURl, models.PostReferenceConfig{}); (err != nil) != tt.wantErr { - t.Errorf("CreateReferenceBetweenPostAndSource() error = %v, wantErr %v", err, tt.wantErr) + if err := p.CreatePostReference(tt.args.ctx, tt.args.anthrovePostID, tt.args.sourceDomain, tt.args.postURl, models.PostReferenceConfig{}); (err != nil) != tt.wantErr { + t.Errorf("CreatePostReference() error = %v, wantErr %v", err, tt.wantErr) } }) } @@ -714,7 +713,7 @@ func Test_postgresqlConnection_CheckReferenceBetweenUserAndPost(t *testing.T) { db: gormDB, debug: true, } - got, err := p.CheckIfUserFavouritedPost(tt.args.ctx, tt.args.anthroveUserID, tt.args.anthrovePostID) + got, err := p.CheckIfUserHasPostAsFavorite(tt.args.ctx, tt.args.anthroveUserID, tt.args.anthrovePostID) if (err != nil) != tt.wantErr { t.Errorf("CheckIfUserHasPostAsFavorite() error = %v, wantErr %v", err, tt.wantErr) return @@ -1235,20 +1234,20 @@ func Test_postgresqlConnection_GetUserSourceBySourceID(t *testing.T) { validSourceID := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source1")) - expectedResult := make(map[string]models.UserSource) - source := &models.Source{ BaseModel: models.BaseModel[models.AnthroveSourceID]{ ID: validSourceID, }, DisplayName: "e621", Domain: "e621.net", + Icon: "https://e621.icon", } - expectedResult["e621"] = models.UserSource{ - UserID: "e1", + expectedResult := &models.UserSource{ + UserID: string(validUserID), AccountUsername: "euser", Source: models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: source.ID}, DisplayName: source.DisplayName, Domain: source.Domain, Icon: source.Icon, @@ -1260,7 +1259,7 @@ func Test_postgresqlConnection_GetUserSourceBySourceID(t *testing.T) { t.Fatal(err) } - err = postgres.CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername) + err = postgres.CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, expectedResult.UserID, expectedResult.AccountUsername) if err != nil { t.Fatal(err) } @@ -1271,10 +1270,11 @@ func Test_postgresqlConnection_GetUserSourceBySourceID(t *testing.T) { anthroveUserID models.AnthroveUserID sourceID models.AnthroveSourceID } + tests := []struct { name string args args - want map[string]models.UserSource + want *models.UserSource wantErr bool }{ { @@ -1349,14 +1349,14 @@ func Test_postgresqlConnection_GetUserSourceBySourceID(t *testing.T) { t.Errorf("GetUserSourceBySourceID() error = %v, wantErr %v", err, tt.wantErr) return } - if !reflect.DeepEqual(got, tt.want) { + if !checkUserSource(got, tt.want) { t.Errorf("GetUserSourceBySourceID() got = %v, want %v", got, tt.want) } }) } } -func Test_postgresqlConnection_GetAllAnthroveUserIDs(t *testing.T) { +func Test_postgresqlConnection_GetAllUsers(t *testing.T) { // Setup trow away container ctx := context.Background() container, gormDB, err := test.StartPostgresContainer(ctx) @@ -1370,10 +1370,20 @@ func Test_postgresqlConnection_GetAllAnthroveUserIDs(t *testing.T) { validUserID02 := models.AnthroveUserID(fmt.Sprintf("%025s", "User2")) validUserID03 := models.AnthroveUserID(fmt.Sprintf("%025s", "User3")) - users := []models.AnthroveUserID{validUserID01, validUserID02, validUserID03} + users := []models.User{ + { + BaseModel: models.BaseModel[models.AnthroveUserID]{ID: validUserID01}, + }, + { + BaseModel: models.BaseModel[models.AnthroveUserID]{ID: validUserID02}, + }, + { + BaseModel: models.BaseModel[models.AnthroveUserID]{ID: validUserID03}, + }, + } for _, user := range users { - err = postgres.CreateUser(ctx, gormDB, user) + err = postgres.CreateUser(ctx, gormDB, user.ID) if err != nil { t.Fatal(err) } @@ -1386,7 +1396,7 @@ func Test_postgresqlConnection_GetAllAnthroveUserIDs(t *testing.T) { tests := []struct { name string args args - want []models.AnthroveUserID + want []models.User wantErr bool }{ { @@ -1403,12 +1413,12 @@ func Test_postgresqlConnection_GetAllAnthroveUserIDs(t *testing.T) { db: gormDB, debug: true, } - got, err := p.GetAllAnthroveUserIDs(tt.args.ctx) + got, err := p.GetAllUsers(tt.args.ctx) if (err != nil) != tt.wantErr { t.Errorf("GetAllUsers() error = %v, wantErr %v", err, tt.wantErr) return } - if !reflect.DeepEqual(got, tt.want) { + if !checkUser(got, tt.want) { t.Errorf("GetAllUsers() got = %v, want %v", got, tt.want) } }) @@ -1975,3 +1985,38 @@ func Test_postgresqlConnection_migrateDatabase(t *testing.T) { }) } } + +func checkUser(got []models.User, want []models.User) bool { + for i, user := range want { + if user.ID != got[i].ID { + return false + } + } + return true +} +func checkUserSource(got *models.UserSource, want *models.UserSource) bool { + + if got == nil && want == nil { + return true + } else if got == nil || want == nil { + return false + } + + if got.UserID != want.UserID { + return false + } + if got.AccountUsername != want.AccountUsername { + return false + } + if got.Source.DisplayName != want.Source.DisplayName { + return false + } + if got.Source.Domain != want.Source.Domain { + return false + } + if got.Source.Icon != want.Source.Icon { + return false + } + + return true +} diff --git a/pkg/database/user.go b/pkg/database/user.go index e7be12e..b74d672 100644 --- a/pkg/database/user.go +++ b/pkg/database/user.go @@ -20,7 +20,7 @@ type User interface { UpdateUserSourceValidation(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, valid bool) error - GetAllUser(ctx context.Context) ([]models.User, error) + GetAllUsers(ctx context.Context) ([]models.User, error) // GetUserFavoritesCount retrieves the count of a user's favorites. GetUserFavoritesCount(ctx context.Context, anthroveUserID models.AnthroveUserID) (int64, error) diff --git a/pkg/models/postReference_test.go b/pkg/models/postReference_test.go index 232a695..d203024 100644 --- a/pkg/models/postReference_test.go +++ b/pkg/models/postReference_test.go @@ -26,13 +26,15 @@ func TestPostReference_TableName(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { po := PostReference{ - PostID: tt.fields.PostID, - SourceID: tt.fields.SourceID, - URL: tt.fields.URL, - SourcePostID: tt.fields.SourcePostID, - FullFileURL: tt.fields.FullFileURL, - PreviewFileURL: tt.fields.PreviewFileURL, - SampleFileURL: tt.fields.SampleFileURL, + PostID: tt.fields.PostID, + SourceID: tt.fields.SourceID, + URL: tt.fields.URL, + PostReferenceConfig: PostReferenceConfig{ + SourcePostID: tt.fields.SourcePostID, + FullFileURL: tt.fields.FullFileURL, + PreviewFileURL: tt.fields.PreviewFileURL, + SampleFileURL: tt.fields.SampleFileURL, + }, } if got := po.TableName(); got != tt.want { t.Errorf("TableName() = %v, want %v", got, tt.want) diff --git a/test/helper.go b/test/helper.go index ce571d2..b16d9d1 100644 --- a/test/helper.go +++ b/test/helper.go @@ -6,6 +6,7 @@ import ( "net/url" "strconv" "strings" + "time" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" migrate "github.com/rubenv/sql-migrate" @@ -22,7 +23,7 @@ const ( databaseName = "anthrove" databaseUser = "anthrove" databasePassword = "anthrove" - migrationSource = "../../pkg/database/migrations" + migrationSource = "../../pkg/database/migrations/" ) func StartPostgresContainer(ctx context.Context) (*postgrescontainer.PostgresContainer, *gorm.DB, error) { @@ -33,7 +34,9 @@ func StartPostgresContainer(ctx context.Context) (*postgrescontainer.PostgresCon postgrescontainer.WithUsername(databaseUser), postgrescontainer.WithPassword(databasePassword), testcontainers.WithWaitStrategy( - wait.ForLog("database system is ready to accept connections"))) + wait.ForLog("database system is ready to accept connections"). + WithOccurrence(2).WithStartupTimeout(60*time.Second)), + ) if err != nil { return nil, nil, err } -- 2.45.1 From bb456583103ae1de98cfca78a765d25d0b95c58b Mon Sep 17 00:00:00 2001 From: SoXX Date: Fri, 28 Jun 2024 15:13:40 +0200 Subject: [PATCH 113/124] feat(TagAlias): added function and tests Signed-off-by: SoXX --- internal/postgres/tag.go | 94 ++++++++++++++++ internal/postgres/tag_test.go | 98 +++++++++++++++++ pkg/database/postgres.go | 86 ++++++++------- pkg/database/postgres_test.go | 194 +++++++++++++++++++++++++--------- 4 files changed, 379 insertions(+), 93 deletions(-) diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 23e23ef..729d57a 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -90,3 +90,97 @@ func GetTags(ctx context.Context, db *gorm.DB) ([]models.Tag, error) { return tags, nil } + +func CreateTagAlias(ctx context.Context, db *gorm.DB, tagAliasName models.AnthroveTagAliasName, tagID models.AnthroveTagID) error { + + if tagAliasName == "" { + return &otterError.EntityValidationFailed{Reason: "tagAliasName cannot be empty"} + } + if tagID == "" { + return &otterError.EntityValidationFailed{Reason: "tagID cannot be empty"} + } + + result := db.WithContext(ctx).Create(&models.TagAlias{ + Name: string(tagAliasName), + TagID: string(tagID), + }) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrDuplicatedKey) { + return &otterError.EntityAlreadyExists{} + } + return result.Error + } + + log.WithFields(log.Fields{ + "tag_alias_name": tagAliasName, + "tag_alias_tag_id": tagID, + }).Trace("database: created tagAlias") + + return nil +} + +func GetAllTagAlias(ctx context.Context, db *gorm.DB) ([]models.TagAlias, error) { + var tagAliases []models.TagAlias + + result := db.WithContext(ctx).Find(&tagAliases) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &otterError.NoDataFound{} + } + return nil, result.Error + } + + log.WithFields(log.Fields{ + "tag_alias_length": len(tagAliases), + }).Trace("database: created tagAlias") + + return tagAliases, nil +} + +func GetAllTagAliasByTag(ctx context.Context, db *gorm.DB, tagID models.AnthroveTagID) ([]models.TagAlias, error) { + var tagAliases []models.TagAlias + + if tagID == "" { + return nil, &otterError.EntityValidationFailed{Reason: "tagID cannot be empty"} + } + + result := db.WithContext(ctx).Where("tag_id = ?", tagID).Find(&tagAliases) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &otterError.NoDataFound{} + } + return nil, result.Error + } + + log.WithFields(log.Fields{ + "tag_alias_length": len(tagAliases), + "tag_alias_tag_id": tagID, + }).Trace("database: get specific tagAlias") + + return tagAliases, nil +} + +func DeleteTagAlias(ctx context.Context, db *gorm.DB, tagAliasName models.AnthroveTagAliasName) error { + + if tagAliasName == "" { + return &otterError.EntityValidationFailed{Reason: "tagAliasName cannot be empty"} + } + + result := db.WithContext(ctx).Delete(&models.TagAlias{Name: string(tagAliasName)}) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return &otterError.NoDataFound{} + } + return result.Error + } + + log.WithFields(log.Fields{ + "tag_alias_name": tagAliasName, + }).Trace("database: deleted tagAlias") + + return nil +} diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index 3f22c76..c18712a 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -246,3 +246,101 @@ func TestCreateTag(t *testing.T) { }) } } + +func TestCreateTagAlias(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validTagAliasName01 := models.AnthroveTagAliasName("httyd") + validTagAliasName02 := models.AnthroveTagAliasName("dragon") + + validTagID := models.AnthroveTagID("toothless") + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + err = CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + tagAliasName models.AnthroveTagAliasName + tagID models.AnthroveTagID + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid Data", + args: args{ + ctx: ctx, + db: gormDB, + tagAliasName: validTagAliasName01, + tagID: validTagID, + }, + wantErr: false, + }, + { + name: "Test 2: No TagAliasName", + args: args{ + ctx: ctx, + db: gormDB, + tagAliasName: "", + tagID: validTagID, + }, + wantErr: true, + }, + { + name: "Test 4: No tagID", + args: args{ + ctx: ctx, + db: gormDB, + tagAliasName: validTagAliasName01, + tagID: "", + }, + wantErr: true, + }, + { + name: "Test 5: Duplicate tagID", + args: args{ + ctx: ctx, + db: gormDB, + tagAliasName: validTagAliasName01, + tagID: validTagID, + }, + wantErr: true, + }, + { + name: "Test 6: Invalide tagID", + args: args{ + ctx: ctx, + db: gormDB, + tagAliasName: validTagAliasName02, + tagID: "aaa", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := CreateTagAlias(tt.args.ctx, tt.args.db, tt.args.tagAliasName, tt.args.tagID); (err != nil) != tt.wantErr { + t.Errorf("CreateTagAlias() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index b63ca0b..d511a84 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -148,50 +148,7 @@ func (p *postgresqlConnection) GetSourceByDomain(ctx context.Context, sourceDoma return postgres.GetSourceByDomain(ctx, p.db, sourceDomain) } -func (p *postgresqlConnection) GetAllTagAlias(ctx context.Context) ([]models.TagAlias, error) { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) GetAllTagAliasByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagAlias, error) { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) CreateTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName, tagID models.AnthroveTagID) error { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) DeleteTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName) error { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) GetAllTagGroup(ctx context.Context) ([]models.TagGroup, error) { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) GetAllTagGroupByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagGroup, error) { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) DeleteTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName) error { - //TODO implement me - panic("implement me") -} - -func (p *postgresqlConnection) UpdateUserWithScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error { - //TODO implement me - panic("implement me") -} +// NEW FUNCTIONS func (p *postgresqlConnection) UpdateUserSourceScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error { //TODO implement me @@ -208,6 +165,47 @@ func (p *postgresqlConnection) UpdateUserSourceValidation(ctx context.Context, a panic("implement me") } +func (p *postgresqlConnection) CreateTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName, tagID models.AnthroveTagID) error { + return postgres.CreateTagAlias(ctx, p.db, tagAliasName, tagID) +} + +func (p *postgresqlConnection) GetAllTagAlias(ctx context.Context) ([]models.TagAlias, error) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) GetAllTagAliasByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagAlias, error) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) DeleteTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName) error { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) GetAllTagGroup(ctx context.Context) ([]models.TagGroup, error) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) GetAllTagGroupByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagGroup, error) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) DeleteTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName) error { + //TODO implement me + panic("implement me") +} + +// HELPER + func (p *postgresqlConnection) migrateDatabase(dbPool *gorm.DB) error { dialect := "postgres" migrations := &migrate.EmbedFileSystemMigrationSource{FileSystem: embedMigrations, Root: "migrations"} diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index 26a46fb..6950118 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -1898,55 +1898,6 @@ func Test_postgresqlConnection_GetSourceByDomain(t *testing.T) { } } -func checkSource(got *models.Source, want *models.Source) bool { - - if want == nil && got == nil { - return true - } - - if got.Domain != want.Domain { - return false - } - - return true - -} - -func checkPost(got *models.Post, want *models.Post) bool { - - if got == nil && want == nil { - return true - } else if got == nil || want == nil { - return false - } - - if got.ID != want.ID { - return false - } - - if got.Rating != want.Rating { - return false - } - - return true -} - -func checkSources(got []models.Source, want []models.Source) bool { - for i, source := range want { - if source.DisplayName != got[i].DisplayName { - return false - } - if source.Domain != got[i].Domain { - return false - } - if source.Icon != got[i].Icon { - return false - } - } - - return true -} - func Test_postgresqlConnection_migrateDatabase(t *testing.T) { // Setup trow away container ctx := context.Background() @@ -1986,6 +1937,53 @@ func Test_postgresqlConnection_migrateDatabase(t *testing.T) { } } +// Helper functions for validation purposes +func checkSource(got *models.Source, want *models.Source) bool { + + if want == nil && got == nil { + return true + } + + if got.Domain != want.Domain { + return false + } + + return true + +} +func checkPost(got *models.Post, want *models.Post) bool { + + if got == nil && want == nil { + return true + } else if got == nil || want == nil { + return false + } + + if got.ID != want.ID { + return false + } + + if got.Rating != want.Rating { + return false + } + + return true +} +func checkSources(got []models.Source, want []models.Source) bool { + for i, source := range want { + if source.DisplayName != got[i].DisplayName { + return false + } + if source.Domain != got[i].Domain { + return false + } + if source.Icon != got[i].Icon { + return false + } + } + + return true +} func checkUser(got []models.User, want []models.User) bool { for i, user := range want { if user.ID != got[i].ID { @@ -2020,3 +2018,101 @@ func checkUserSource(got *models.UserSource, want *models.UserSource) bool { return true } + +//------------------------- + +func Test_postgresqlConnection_CreateTagAlias(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validTagAliasName01 := models.AnthroveTagAliasName("httyd") + validTagAliasName02 := models.AnthroveTagAliasName("dragon") + + validTagID := models.AnthroveTagID("toothless") + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + err = postgres.CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + tagAliasName models.AnthroveTagAliasName + tagID models.AnthroveTagID + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid Data", + args: args{ + ctx: ctx, + tagAliasName: validTagAliasName01, + tagID: validTagID, + }, + wantErr: false, + }, + { + name: "Test 2: No TagAliasName", + args: args{ + ctx: ctx, + tagAliasName: "", + tagID: validTagID, + }, + wantErr: true, + }, + { + name: "Test 4: No tagID", + args: args{ + ctx: ctx, + tagAliasName: validTagAliasName01, + tagID: "", + }, + wantErr: true, + }, + { + name: "Test 5: Duplicate tagID", + args: args{ + ctx: ctx, + tagAliasName: validTagAliasName01, + tagID: validTagID, + }, + wantErr: true, + }, + { + name: "Test 6: Invalide tagID", + args: args{ + ctx: ctx, + tagAliasName: validTagAliasName02, + tagID: "aaa", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.CreateTagAlias(tt.args.ctx, tt.args.tagAliasName, tt.args.tagID); (err != nil) != tt.wantErr { + t.Errorf("CreateTagAlias() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} -- 2.45.1 From 26178eb64d6c0949005e6748d9a734ef2a49cb0d Mon Sep 17 00:00:00 2001 From: SoXX Date: Fri, 28 Jun 2024 22:14:27 +0200 Subject: [PATCH 114/124] feat(TagAlias): added function and tests Signed-off-by: SoXX --- internal/postgres/tag_test.go | 78 +++++++++++++++++++++++++++++++++++ pkg/database/postgres.go | 3 +- pkg/database/postgres_test.go | 77 ++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 2 deletions(-) diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index c18712a..8e51eb9 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -3,6 +3,7 @@ package postgres import ( "context" "fmt" + "reflect" "testing" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" @@ -344,3 +345,80 @@ func TestCreateTagAlias(t *testing.T) { }) } } + +func TestGetAllTagAlias(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validTagID := models.AnthroveTagID("toothless") + validTagAliases := []models.AnthroveTagAliasName{"httyd", "dragon", "scaly"} + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + expectedResult := []models.TagAlias{ + { + Name: string(validTagAliases[0]), + TagID: string(validTagID), + }, + { + Name: string(validTagAliases[1]), + TagID: string(validTagID), + }, + { + Name: string(validTagAliases[2]), + TagID: string(validTagID), + }, + } + + err = CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + for _, tagAliasName := range validTagAliases { + err = CreateTagAlias(ctx, gormDB, tagAliasName, validTagID) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + } + tests := []struct { + name string + args args + want []models.TagAlias + wantErr bool + }{ + { + name: "Test 1: Get Data", + args: args{ + ctx: ctx, + db: gormDB, + }, + want: expectedResult, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetAllTagAlias(tt.args.ctx, tt.args.db) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllTagAlias() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetAllTagAlias() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index d511a84..bb1e8c0 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -170,8 +170,7 @@ func (p *postgresqlConnection) CreateTagAlias(ctx context.Context, tagAliasName } func (p *postgresqlConnection) GetAllTagAlias(ctx context.Context) ([]models.TagAlias, error) { - //TODO implement me - panic("implement me") + return postgres.GetAllTagAlias(ctx, p.db) } func (p *postgresqlConnection) GetAllTagAliasByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagAlias, error) { diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index 6950118..dbcd844 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -2116,3 +2116,80 @@ func Test_postgresqlConnection_CreateTagAlias(t *testing.T) { }) } } + +func Test_postgresqlConnection_GetAllTagAlias(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validTagID := models.AnthroveTagID("toothless") + validTagAliases := []models.AnthroveTagAliasName{"httyd", "dragon", "scaly"} + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + expectedResult := []models.TagAlias{ + { + Name: string(validTagAliases[0]), + TagID: string(validTagID), + }, + { + Name: string(validTagAliases[1]), + TagID: string(validTagID), + }, + { + Name: string(validTagAliases[2]), + TagID: string(validTagID), + }, + } + + err = postgres.CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + for _, tagAliasName := range validTagAliases { + err = postgres.CreateTagAlias(ctx, gormDB, tagAliasName, validTagID) + } + + // Test + type args struct { + ctx context.Context + } + tests := []struct { + name string + args args + want []models.TagAlias + wantErr bool + }{ + { + name: "Test 1: Get Data", + args: args{ctx: ctx}, + want: expectedResult, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetAllTagAlias(tt.args.ctx) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllTagAlias() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetAllTagAlias() got = %v, want %v", got, tt.want) + } + }) + } +} -- 2.45.1 From 702870db1e87036a8965633409437a77bd19269b Mon Sep 17 00:00:00 2001 From: SoXX Date: Fri, 28 Jun 2024 22:27:31 +0200 Subject: [PATCH 115/124] feat(TagAlias): added function and tests Signed-off-by: SoXX --- internal/postgres/tag_test.go | 174 ++++++++++++++++++++++++++++++++++ pkg/database/postgres.go | 6 +- pkg/database/postgres_test.go | 174 ++++++++++++++++++++++++++++++++++ 3 files changed, 350 insertions(+), 4 deletions(-) diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index 8e51eb9..54f8c03 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -422,3 +422,177 @@ func TestGetAllTagAlias(t *testing.T) { }) } } + +func TestGetAllTagAliasByTag(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validTagID := models.AnthroveTagID("toothless") + validTagAliases := []models.AnthroveTagAliasName{"httyd", "dragon", "scaly"} + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + expectedResult := []models.TagAlias{ + { + Name: string(validTagAliases[0]), + TagID: string(validTagID), + }, + { + Name: string(validTagAliases[1]), + TagID: string(validTagID), + }, + { + Name: string(validTagAliases[2]), + TagID: string(validTagID), + }, + } + + err = CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + for _, tagAliasName := range validTagAliases { + err = CreateTagAlias(ctx, gormDB, tagAliasName, validTagID) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + tagID models.AnthroveTagID + } + tests := []struct { + name string + args args + want []models.TagAlias + wantErr bool + }{ + { + name: "Test 1: Valid TagID", + args: args{ + ctx: ctx, + db: gormDB, + tagID: validTagID, + }, + want: expectedResult, + wantErr: false, + }, + { + name: "Test 2: No TagID", + args: args{ + ctx: ctx, + db: gormDB, + tagID: "", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 3: Invalid TagID", + args: args{ + ctx: ctx, + db: gormDB, + tagID: "adads", + }, + want: []models.TagAlias{}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetAllTagAliasByTag(tt.args.ctx, tt.args.db, tt.args.tagID) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllTagAliasByTag() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetAllTagAliasByTag() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestDeleteTagAlias(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validTagID := models.AnthroveTagID("toothless") + validTagAliases := []models.AnthroveTagAliasName{"httyd", "dragon", "scaly"} + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + err = CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + for _, tagAliasName := range validTagAliases { + err = CreateTagAlias(ctx, gormDB, tagAliasName, validTagID) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + tagAliasName models.AnthroveTagAliasName + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid AnthroveTagAliasName", + args: args{ + ctx: ctx, + db: gormDB, + tagAliasName: validTagAliases[0], + }, + wantErr: false, + }, + { + name: "Test 2: Invalid AnthroveTagAliasName", + args: args{ + ctx: ctx, + db: gormDB, + tagAliasName: "asdad", + }, + wantErr: false, + }, + { + name: "Test 3: No AnthroveTagAliasName", + args: args{ + ctx: ctx, + db: gormDB, + tagAliasName: "", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := DeleteTagAlias(tt.args.ctx, tt.args.db, tt.args.tagAliasName); (err != nil) != tt.wantErr { + t.Errorf("DeleteTagAlias() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index bb1e8c0..1eb22de 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -174,13 +174,11 @@ func (p *postgresqlConnection) GetAllTagAlias(ctx context.Context) ([]models.Tag } func (p *postgresqlConnection) GetAllTagAliasByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagAlias, error) { - //TODO implement me - panic("implement me") + return postgres.GetAllTagAliasByTag(ctx, p.db, tagID) } func (p *postgresqlConnection) DeleteTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName) error { - //TODO implement me - panic("implement me") + return postgres.DeleteTagAlias(ctx, p.db, tagAliasName) } func (p *postgresqlConnection) CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) { diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index dbcd844..acd0b0e 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -2193,3 +2193,177 @@ func Test_postgresqlConnection_GetAllTagAlias(t *testing.T) { }) } } + +func Test_postgresqlConnection_GetAllTagAliasByTag(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validTagID := models.AnthroveTagID("toothless") + validTagAliases := []models.AnthroveTagAliasName{"httyd", "dragon", "scaly"} + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + expectedResult := []models.TagAlias{ + { + Name: string(validTagAliases[0]), + TagID: string(validTagID), + }, + { + Name: string(validTagAliases[1]), + TagID: string(validTagID), + }, + { + Name: string(validTagAliases[2]), + TagID: string(validTagID), + }, + } + + err = postgres.CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + for _, tagAliasName := range validTagAliases { + err = postgres.CreateTagAlias(ctx, gormDB, tagAliasName, validTagID) + } + + // Test + type args struct { + ctx context.Context + tagID models.AnthroveTagID + } + tests := []struct { + name string + args args + want []models.TagAlias + wantErr bool + }{ + { + name: "Test 1: Valid TagID", + args: args{ + ctx: ctx, + tagID: validTagID, + }, + want: expectedResult, + wantErr: false, + }, + { + name: "Test 2: No TagID", + args: args{ + ctx: ctx, + tagID: "", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 3: Invalid TagID", + args: args{ + ctx: ctx, + tagID: "adads", + }, + want: []models.TagAlias{}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetAllTagAliasByTag(tt.args.ctx, tt.args.tagID) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllTagAliasByTag() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetAllTagAliasByTag() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_postgresqlConnection_DeleteTagAlias(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validTagID := models.AnthroveTagID("toothless") + validTagAliases := []models.AnthroveTagAliasName{"httyd", "dragon", "scaly"} + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + err = postgres.CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + for _, tagAliasName := range validTagAliases { + err = postgres.CreateTagAlias(ctx, gormDB, tagAliasName, validTagID) + } + + // Test + type args struct { + ctx context.Context + tagAliasName models.AnthroveTagAliasName + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid AnthroveTagAliasName", + args: args{ + ctx: ctx, + tagAliasName: validTagAliases[0], + }, + wantErr: false, + }, + { + name: "Test 2: Invalid AnthroveTagAliasName", + args: args{ + ctx: ctx, + tagAliasName: "asdad", + }, + wantErr: false, + }, + { + name: "Test 3: No AnthroveTagAliasName", + args: args{ + ctx: ctx, + tagAliasName: "", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.DeleteTagAlias(tt.args.ctx, tt.args.tagAliasName); (err != nil) != tt.wantErr { + t.Errorf("DeleteTagAlias() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} -- 2.45.1 From d759e072f77751f725e3f2f46fa34f79b3781917 Mon Sep 17 00:00:00 2001 From: SoXX Date: Fri, 28 Jun 2024 22:39:12 +0200 Subject: [PATCH 116/124] feat(TagGroup): added function and tests Signed-off-by: SoXX --- internal/postgres/tag.go | 94 +++++++++ internal/postgres/tag_test.go | 349 ++++++++++++++++++++++++++++++++++ pkg/database/postgres.go | 14 +- pkg/database/postgres_test.go | 349 ++++++++++++++++++++++++++++++++++ pkg/database/taggroup.go | 2 +- 5 files changed, 798 insertions(+), 10 deletions(-) diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 729d57a..4e851e2 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -184,3 +184,97 @@ func DeleteTagAlias(ctx context.Context, db *gorm.DB, tagAliasName models.Anthro return nil } + +func CreateTagGroup(ctx context.Context, db *gorm.DB, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) error { + + if tagGroupName == "" { + return &otterError.EntityValidationFailed{Reason: "tagGroupName cannot be empty"} + } + if tagID == "" { + return &otterError.EntityValidationFailed{Reason: "tagID cannot be empty"} + } + + result := db.WithContext(ctx).Create(&models.TagGroup{ + Name: string(tagGroupName), + TagID: string(tagID), + }) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrDuplicatedKey) { + return &otterError.EntityAlreadyExists{} + } + return result.Error + } + + log.WithFields(log.Fields{ + "tag_group_name": tagGroupName, + "tag_group_tag_id": tagID, + }).Trace("database: created tagGroup") + + return nil +} + +func GetAllTagGroup(ctx context.Context, db *gorm.DB) ([]models.TagGroup, error) { + var tagGroups []models.TagGroup + + result := db.WithContext(ctx).Find(&tagGroups) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &otterError.NoDataFound{} + } + return nil, result.Error + } + + log.WithFields(log.Fields{ + "tag_alias_length": len(tagGroups), + }).Trace("database: created tagGroup") + + return tagGroups, nil +} + +func GetAllTagGroupByTag(ctx context.Context, db *gorm.DB, tagID models.AnthroveTagID) ([]models.TagGroup, error) { + var tagGroups []models.TagGroup + + if tagID == "" { + return nil, &otterError.EntityValidationFailed{Reason: "tagID cannot be empty"} + } + + result := db.WithContext(ctx).Where("tag_id = ?", tagID).Find(&tagGroups) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &otterError.NoDataFound{} + } + return nil, result.Error + } + + log.WithFields(log.Fields{ + "tag_alias_length": len(tagGroups), + "tag_alias_tag_id": tagID, + }).Trace("database: get specific tagGroup") + + return tagGroups, nil +} + +func DeleteTagGroup(ctx context.Context, db *gorm.DB, tagGroupName models.AnthroveTagGroupName) error { + + if tagGroupName == "" { + return &otterError.EntityValidationFailed{Reason: "tagGroupName cannot be empty"} + } + + result := db.WithContext(ctx).Delete(&models.TagGroup{Name: string(tagGroupName)}) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return &otterError.NoDataFound{} + } + return result.Error + } + + log.WithFields(log.Fields{ + "tag_alias_name": tagGroupName, + }).Trace("database: deleted tagAlias") + + return nil +} diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index 54f8c03..adbc867 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -596,3 +596,352 @@ func TestDeleteTagAlias(t *testing.T) { }) } } + +func TestCreateTagGroup(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validTagGroupName01 := models.AnthroveTagGroupName("httyd") + validTagGroupName02 := models.AnthroveTagGroupName("dragon") + + validTagID := models.AnthroveTagID("toothless") + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + err = CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + tagGroupName models.AnthroveTagGroupName + tagID models.AnthroveTagID + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid Data", + args: args{ + ctx: ctx, + db: gormDB, + tagGroupName: validTagGroupName01, + tagID: validTagID, + }, + wantErr: false, + }, + { + name: "Test 2: No TagGroupName", + args: args{ + ctx: ctx, + db: gormDB, + tagGroupName: "", + tagID: validTagID, + }, + wantErr: true, + }, + { + name: "Test 4: No tagID", + args: args{ + ctx: ctx, + db: gormDB, + tagGroupName: validTagGroupName01, + tagID: "", + }, + wantErr: true, + }, + { + name: "Test 5: Duplicate tagID", + args: args{ + ctx: ctx, + db: gormDB, + tagGroupName: validTagGroupName01, + tagID: validTagID, + }, + wantErr: true, + }, + { + name: "Test 6: Invalide tagID", + args: args{ + ctx: ctx, + db: gormDB, + tagGroupName: validTagGroupName02, + tagID: "aaa", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := CreateTagGroup(tt.args.ctx, tt.args.db, tt.args.tagGroupName, tt.args.tagID); (err != nil) != tt.wantErr { + t.Errorf("CreateTagGroup() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestGetAllTagGroup(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validTagID := models.AnthroveTagID("toothless") + validTagGroupes := []models.AnthroveTagGroupName{"httyd", "dragon", "scaly"} + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + expectedResult := []models.TagGroup{ + { + Name: string(validTagGroupes[0]), + TagID: string(validTagID), + }, + { + Name: string(validTagGroupes[1]), + TagID: string(validTagID), + }, + { + Name: string(validTagGroupes[2]), + TagID: string(validTagID), + }, + } + + err = CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + for _, tagGroupName := range validTagGroupes { + err = CreateTagGroup(ctx, gormDB, tagGroupName, validTagID) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + } + tests := []struct { + name string + args args + want []models.TagGroup + wantErr bool + }{ + { + name: "Test 1: Get Data", + args: args{ + ctx: ctx, + db: gormDB, + }, + want: expectedResult, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetAllTagGroup(tt.args.ctx, tt.args.db) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllTagGroup() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetAllTagGroup() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGetAllTagGroupByTag(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validTagID := models.AnthroveTagID("toothless") + validTagGroupes := []models.AnthroveTagGroupName{"httyd", "dragon", "scaly"} + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + expectedResult := []models.TagGroup{ + { + Name: string(validTagGroupes[0]), + TagID: string(validTagID), + }, + { + Name: string(validTagGroupes[1]), + TagID: string(validTagID), + }, + { + Name: string(validTagGroupes[2]), + TagID: string(validTagID), + }, + } + + err = CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + for _, tagGroupName := range validTagGroupes { + err = CreateTagGroup(ctx, gormDB, tagGroupName, validTagID) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + tagID models.AnthroveTagID + } + tests := []struct { + name string + args args + want []models.TagGroup + wantErr bool + }{ + { + name: "Test 1: Valid TagID", + args: args{ + ctx: ctx, + db: gormDB, + tagID: validTagID, + }, + want: expectedResult, + wantErr: false, + }, + { + name: "Test 2: No TagID", + args: args{ + ctx: ctx, + db: gormDB, + tagID: "", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 3: Invalid TagID", + args: args{ + ctx: ctx, + db: gormDB, + tagID: "adads", + }, + want: []models.TagGroup{}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetAllTagGroupByTag(tt.args.ctx, tt.args.db, tt.args.tagID) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllTagGroupByTag() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetAllTagGroupByTag() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestDeleteTagGroup(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validTagID := models.AnthroveTagID("toothless") + validTagGroupes := []models.AnthroveTagGroupName{"httyd", "dragon", "scaly"} + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + err = CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + for _, tagGroupName := range validTagGroupes { + err = CreateTagGroup(ctx, gormDB, tagGroupName, validTagID) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + tagGroupName models.AnthroveTagGroupName + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid AnthroveTagGroupName", + args: args{ + ctx: ctx, + db: gormDB, + tagGroupName: validTagGroupes[0], + }, + wantErr: false, + }, + { + name: "Test 2: Invalid AnthroveTagGroupName", + args: args{ + ctx: ctx, + db: gormDB, + tagGroupName: "asdad", + }, + wantErr: false, + }, + { + name: "Test 3: No AnthroveTagGroupName", + args: args{ + ctx: ctx, + db: gormDB, + tagGroupName: "", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := DeleteTagGroup(tt.args.ctx, tt.args.db, tt.args.tagGroupName); (err != nil) != tt.wantErr { + t.Errorf("DeleteTagAlias() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 1eb22de..39c7a54 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -181,24 +181,20 @@ func (p *postgresqlConnection) DeleteTagAlias(ctx context.Context, tagAliasName return postgres.DeleteTagAlias(ctx, p.db, tagAliasName) } -func (p *postgresqlConnection) CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) { - //TODO implement me - panic("implement me") +func (p *postgresqlConnection) CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) error { + return postgres.CreateTagGroup(ctx, p.db, tagGroupName, tagID) } func (p *postgresqlConnection) GetAllTagGroup(ctx context.Context) ([]models.TagGroup, error) { - //TODO implement me - panic("implement me") + return postgres.GetAllTagGroup(ctx, p.db) } func (p *postgresqlConnection) GetAllTagGroupByTag(ctx context.Context, tagID models.AnthroveTagID) ([]models.TagGroup, error) { - //TODO implement me - panic("implement me") + return postgres.GetAllTagGroupByTag(ctx, p.db, tagID) } func (p *postgresqlConnection) DeleteTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName) error { - //TODO implement me - panic("implement me") + return postgres.DeleteTagGroup(ctx, p.db, tagGroupName) } // HELPER diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index acd0b0e..d53f9e2 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -2367,3 +2367,352 @@ func Test_postgresqlConnection_DeleteTagAlias(t *testing.T) { }) } } + +//-------------------------- + +func Test_postgresqlConnection_CreateTagGroup(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validTagGroupName01 := models.AnthroveTagGroupName("httyd") + validTagGroupName02 := models.AnthroveTagGroupName("dragon") + + validTagID := models.AnthroveTagID("toothless") + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + err = postgres.CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + tagGroupName models.AnthroveTagGroupName + tagID models.AnthroveTagID + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid Data", + args: args{ + ctx: ctx, + tagGroupName: validTagGroupName01, + tagID: validTagID, + }, + wantErr: false, + }, + { + name: "Test 2: No TagGroupName", + args: args{ + ctx: ctx, + tagGroupName: "", + tagID: validTagID, + }, + wantErr: true, + }, + { + name: "Test 4: No tagID", + args: args{ + ctx: ctx, + tagGroupName: validTagGroupName01, + tagID: "", + }, + wantErr: true, + }, + { + name: "Test 5: Duplicate tagID", + args: args{ + ctx: ctx, + tagGroupName: validTagGroupName01, + tagID: validTagID, + }, + wantErr: true, + }, + { + name: "Test 6: Invalide tagID", + args: args{ + ctx: ctx, + tagGroupName: validTagGroupName02, + tagID: "aaa", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.CreateTagGroup(tt.args.ctx, tt.args.tagGroupName, tt.args.tagID); (err != nil) != tt.wantErr { + t.Errorf("CreateTagGroup() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_postgresqlConnection_GetAllTagGroup(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validTagID := models.AnthroveTagID("toothless") + validTagGroupes := []models.AnthroveTagGroupName{"httyd", "dragon", "scaly"} + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + expectedResult := []models.TagGroup{ + { + Name: string(validTagGroupes[0]), + TagID: string(validTagID), + }, + { + Name: string(validTagGroupes[1]), + TagID: string(validTagID), + }, + { + Name: string(validTagGroupes[2]), + TagID: string(validTagID), + }, + } + + err = postgres.CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + for _, tagGroupName := range validTagGroupes { + err = postgres.CreateTagGroup(ctx, gormDB, tagGroupName, validTagID) + } + + // Test + type args struct { + ctx context.Context + } + tests := []struct { + name string + args args + want []models.TagGroup + wantErr bool + }{ + { + name: "Test 1: Get Data", + args: args{ctx: ctx}, + want: expectedResult, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetAllTagGroup(tt.args.ctx) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllTagGroup() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetAllTagGroup() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_postgresqlConnection_GetAllTagGroupByTag(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validTagID := models.AnthroveTagID("toothless") + validTagGroupes := []models.AnthroveTagGroupName{"httyd", "dragon", "scaly"} + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + expectedResult := []models.TagGroup{ + { + Name: string(validTagGroupes[0]), + TagID: string(validTagID), + }, + { + Name: string(validTagGroupes[1]), + TagID: string(validTagID), + }, + { + Name: string(validTagGroupes[2]), + TagID: string(validTagID), + }, + } + + err = postgres.CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + for _, tagGroupName := range validTagGroupes { + err = postgres.CreateTagGroup(ctx, gormDB, tagGroupName, validTagID) + } + + // Test + type args struct { + ctx context.Context + tagID models.AnthroveTagID + } + tests := []struct { + name string + args args + want []models.TagGroup + wantErr bool + }{ + { + name: "Test 1: Valid TagID", + args: args{ + ctx: ctx, + tagID: validTagID, + }, + want: expectedResult, + wantErr: false, + }, + { + name: "Test 2: No TagID", + args: args{ + ctx: ctx, + tagID: "", + }, + want: nil, + wantErr: true, + }, + { + name: "Test 3: Invalid TagID", + args: args{ + ctx: ctx, + tagID: "adads", + }, + want: []models.TagGroup{}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetAllTagGroupByTag(tt.args.ctx, tt.args.tagID) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllTagGroupByTag() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetAllTagGroupByTag() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_postgresqlConnection_DeleteTagGroup(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validTagID := models.AnthroveTagID("toothless") + validTagGroupes := []models.AnthroveTagGroupName{"httyd", "dragon", "scaly"} + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + err = postgres.CreateTag(ctx, gormDB, validTag) + if err != nil { + t.Fatal(err) + } + + for _, tagGroupName := range validTagGroupes { + err = postgres.CreateTagGroup(ctx, gormDB, tagGroupName, validTagID) + } + + // Test + type args struct { + ctx context.Context + tagGroupName models.AnthroveTagGroupName + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid AnthroveTagGroupName", + args: args{ + ctx: ctx, + tagGroupName: validTagGroupes[0], + }, + wantErr: false, + }, + { + name: "Test 2: Invalid AnthroveTagGroupName", + args: args{ + ctx: ctx, + tagGroupName: "asdad", + }, + wantErr: false, + }, + { + name: "Test 3: No AnthroveTagGroupName", + args: args{ + ctx: ctx, + tagGroupName: "", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.DeleteTagGroup(tt.args.ctx, tt.args.tagGroupName); (err != nil) != tt.wantErr { + t.Errorf("DeleteTagAlias() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/database/taggroup.go b/pkg/database/taggroup.go index 594cd1e..f25bd68 100644 --- a/pkg/database/taggroup.go +++ b/pkg/database/taggroup.go @@ -7,7 +7,7 @@ import ( ) type TagGroup interface { - CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) + CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) error GetAllTagGroup(ctx context.Context) ([]models.TagGroup, error) -- 2.45.1 From 6ccd593d8888cbb37e2fbdae64e94648e040eb0d Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 1 Jul 2024 11:36:21 +0200 Subject: [PATCH 117/124] refactor: changed code layout Signed-off-by: SoXX --- internal/postgres/user.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/postgres/user.go b/internal/postgres/user.go index c0a2543..042154f 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -11,6 +11,13 @@ import ( "gorm.io/gorm" ) +// Workaround, should be changed later maybe, but its not that bad right now +type selectFrequencyTag struct { + tagName string `gorm:"tag_name"` + count int64 `gorm:"count"` + tagType models.TagType `gorm:"tag_type"` +} + func CreateUser(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) error { if anthroveUserID == "" { @@ -267,13 +274,6 @@ func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUse return &models.FavoriteList{Posts: favoritePosts}, nil } -// Workaround, should be changed later maybe, but its not that bad right now -type selectFrequencyTag struct { - tagName string `gorm:"tag_name"` - count int64 `gorm:"count"` - tagType models.TagType `gorm:"tag_type"` -} - func GetUserTagWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) { var queryUserFavorites []selectFrequencyTag -- 2.45.1 From 5f9ace9bd35077cf7eb55801e46f18f900bb6ba9 Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 1 Jul 2024 13:42:53 +0200 Subject: [PATCH 118/124] feat: implemented all functions Signed-off-by: SoXX --- internal/postgres/user.go | 99 +++++++++ internal/postgres/user_test.go | 365 +++++++++++++++++++++++++++++++++ pkg/database/postgres.go | 9 +- pkg/database/postgres_test.go | 357 ++++++++++++++++++++++++++++++++ pkg/error/validation.go | 6 +- pkg/models/const.go | 4 +- 6 files changed, 831 insertions(+), 9 deletions(-) diff --git a/internal/postgres/user.go b/internal/postgres/user.go index 042154f..5037a17 100644 --- a/internal/postgres/user.go +++ b/internal/postgres/user.go @@ -3,6 +3,7 @@ package postgres import ( "context" "errors" + "time" otterError "git.dragse.it/anthrove/otter-space-sdk/pkg/error" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" @@ -320,3 +321,101 @@ func GetUserTagWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthrov return userFavoritesFrequency, nil } + +func UpdateUserSourceScrapeTimeInterval(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error { + + if anthroveUserID == "" { + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} + } + + if len(anthroveUserID) != 25 { + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort} + } + + if sourceID == "" { + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveSourceIDEmpty} + } + + if len(sourceID) != 25 { + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveSourceIDToShort} + } + + if scrapeTime == 0 { + return &otterError.EntityValidationFailed{Reason: "ScrapeTimeInterval cannot be empty"} + } + + userSource := &models.UserSource{ + UserID: string(anthroveUserID), + } + + result := db.WithContext(ctx).Model(&userSource).Update("scrape_time_interval", scrapeTime) + if result.Error != nil { + return result.Error + } + + return nil +} + +func UpdateUserSourceLastScrapeTime(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, lastScrapeTime models.AnthroveUserLastScrapeTime) error { + + if anthroveUserID == "" { + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} + } + + if len(anthroveUserID) != 25 { + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort} + } + + if sourceID == "" { + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveSourceIDEmpty} + } + + if len(sourceID) != 25 { + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveSourceIDToShort} + } + + if time.Time.IsZero(time.Time(lastScrapeTime)) { + return &otterError.EntityValidationFailed{Reason: "LastScrapeTime cannot be empty"} + } + + userSource := &models.UserSource{ + UserID: string(anthroveUserID), + } + + result := db.WithContext(ctx).Model(&userSource).Update("last_scrape_time", time.Time(lastScrapeTime)) + if result.Error != nil { + return result.Error + } + + return nil +} + +func UpdateUserSourceValidation(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, valid bool) error { + + if anthroveUserID == "" { + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty} + } + + if len(anthroveUserID) != 25 { + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort} + } + + if sourceID == "" { + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveSourceIDEmpty} + } + + if len(sourceID) != 25 { + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveSourceIDToShort} + } + + userSource := &models.UserSource{ + UserID: string(anthroveUserID), + } + + result := db.WithContext(ctx).Model(&userSource).Update("account_validate", valid) + if result.Error != nil { + return result.Error + } + + return nil +} diff --git a/internal/postgres/user_test.go b/internal/postgres/user_test.go index 8dfa13a..c8be97a 100644 --- a/internal/postgres/user_test.go +++ b/internal/postgres/user_test.go @@ -5,6 +5,7 @@ import ( "fmt" "reflect" "testing" + "time" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/test" @@ -986,3 +987,367 @@ func checkUserSource(got *models.UserSource, want *models.UserSource) bool { return true } + +func TestUpdateUserSourceScrapeTimeInterval(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + invalidUserID := models.AnthroveUserID("XXX") + + validSourceID := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source1")) + + source := &models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ + ID: validSourceID, + }, + DisplayName: "e621", + Domain: "e621.net", + Icon: "https://e621.icon", + } + + err = CreateSource(ctx, gormDB, source) + if err != nil { + t.Fatal(err) + } + + err = CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, "e66e6e6e6", "euser") + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + anthroveUserID models.AnthroveUserID + sourceID models.AnthroveSourceID + scrapeTime models.AnthroveScrapeTimeInterval + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid Data", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: validUserID, + sourceID: validSourceID, + scrapeTime: 10, + }, + wantErr: false, + }, + { + name: "Test 2: anthroveUserID to short", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: invalidUserID, + sourceID: validSourceID, + scrapeTime: 10, + }, + wantErr: true, + }, + { + name: "Test 3: anthroveUserID is empty", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "", + sourceID: validSourceID, + scrapeTime: 10, + }, + wantErr: true, + }, + { + name: "Test 4: anthroveUserID to short", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: validUserID, + sourceID: "111", + scrapeTime: 10, + }, + wantErr: true, + }, + { + name: "Test 5: anthroveUserID is empty", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: validUserID, + sourceID: "", + scrapeTime: 10, + }, + wantErr: true, + }, + { + name: "Test 5: scrapeTime is empty", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: validUserID, + sourceID: validSourceID, + scrapeTime: 0, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := UpdateUserSourceScrapeTimeInterval(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.sourceID, tt.args.scrapeTime); (err != nil) != tt.wantErr { + t.Errorf("UpdateUserSourceScrapeTimeInterval() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestUpdateUserSourceLastScrapeTime(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + invalidUserID := models.AnthroveUserID("XXX") + + validSourceID := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source1")) + + validScrapeTime := models.AnthroveUserLastScrapeTime(time.Now()) + inValidScrapeTime := models.AnthroveUserLastScrapeTime{} + + source := &models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ + ID: validSourceID, + }, + DisplayName: "e621", + Domain: "e621.net", + Icon: "https://e621.icon", + } + + err = CreateSource(ctx, gormDB, source) + if err != nil { + t.Fatal(err) + } + + err = CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, "e66e6e6e6", "euser") + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + anthroveUserID models.AnthroveUserID + sourceID models.AnthroveSourceID + lastScrapeTime models.AnthroveUserLastScrapeTime + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid Data", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: validUserID, + sourceID: validSourceID, + lastScrapeTime: validScrapeTime, + }, + wantErr: false, + }, + { + name: "Test 2: anthroveUserID to short", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: invalidUserID, + sourceID: validSourceID, + lastScrapeTime: validScrapeTime, + }, + wantErr: true, + }, + { + name: "Test 3: anthroveUserID is empty", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "", + sourceID: validSourceID, + lastScrapeTime: validScrapeTime, + }, + wantErr: true, + }, + { + name: "Test 4: anthroveUserID to short", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: validUserID, + sourceID: "111", + lastScrapeTime: validScrapeTime, + }, + wantErr: true, + }, + { + name: "Test 5: anthroveUserID is empty", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: validUserID, + sourceID: "", + lastScrapeTime: validScrapeTime, + }, + wantErr: true, + }, + { + name: "Test 5: scrapeTime is empty", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: validUserID, + sourceID: validSourceID, + lastScrapeTime: inValidScrapeTime, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := UpdateUserSourceLastScrapeTime(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.sourceID, tt.args.lastScrapeTime); (err != nil) != tt.wantErr { + t.Errorf("UpdateUserSourceLastScrapeTime() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestUpdateUserSourceValidation(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + invalidUserID := models.AnthroveUserID("XXX") + + validSourceID := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source1")) + + source := &models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ + ID: validSourceID, + }, + DisplayName: "e621", + Domain: "e621.net", + Icon: "https://e621.icon", + } + + err = CreateSource(ctx, gormDB, source) + if err != nil { + t.Fatal(err) + } + + err = CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, "e66e6e6e6", "euser") + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + anthroveUserID models.AnthroveUserID + sourceID models.AnthroveSourceID + valid bool + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid Data", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: validUserID, + sourceID: validSourceID, + valid: true, + }, + wantErr: false, + }, + { + name: "Test 2: anthroveUserID to short", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: invalidUserID, + sourceID: validSourceID, + valid: true, + }, + wantErr: true, + }, + { + name: "Test 3: anthroveUserID is empty", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: "", + sourceID: validSourceID, + valid: true, + }, + wantErr: true, + }, + { + name: "Test 4: anthroveUserID to short", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: validUserID, + sourceID: "111", + valid: true, + }, + wantErr: true, + }, + { + name: "Test 5: anthroveUserID is empty", + args: args{ + ctx: ctx, + db: gormDB, + anthroveUserID: validUserID, + sourceID: "", + valid: true, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := UpdateUserSourceValidation(tt.args.ctx, tt.args.db, tt.args.anthroveUserID, tt.args.sourceID, tt.args.valid); (err != nil) != tt.wantErr { + t.Errorf("UpdateUserSourceValidation() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 39c7a54..6d3dd07 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -151,18 +151,15 @@ func (p *postgresqlConnection) GetSourceByDomain(ctx context.Context, sourceDoma // NEW FUNCTIONS func (p *postgresqlConnection) UpdateUserSourceScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error { - //TODO implement me - panic("implement me") + return postgres.UpdateUserSourceScrapeTimeInterval(ctx, p.db, anthroveUserID, sourceID, scrapeTime) } func (p *postgresqlConnection) UpdateUserSourceLastScrapeTime(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, lastScrapeTime models.AnthroveUserLastScrapeTime) error { - //TODO implement me - panic("implement me") + return postgres.UpdateUserSourceLastScrapeTime(ctx, p.db, anthroveUserID, sourceID, lastScrapeTime) } func (p *postgresqlConnection) UpdateUserSourceValidation(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, valid bool) error { - //TODO implement me - panic("implement me") + return postgres.UpdateUserSourceValidation(ctx, p.db, anthroveUserID, sourceID, valid) } func (p *postgresqlConnection) CreateTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName, tagID models.AnthroveTagID) error { diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index d53f9e2..93534cc 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -5,6 +5,7 @@ import ( "fmt" "reflect" "testing" + "time" "git.dragse.it/anthrove/otter-space-sdk/internal/postgres" "git.dragse.it/anthrove/otter-space-sdk/pkg/models" @@ -2716,3 +2717,359 @@ func Test_postgresqlConnection_DeleteTagGroup(t *testing.T) { }) } } + +func Test_postgresqlConnection_UpdateUserSourceScrapeTimeInterval(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + invalidUserID := models.AnthroveUserID("XXX") + + validSourceID := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source1")) + + source := &models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ + ID: validSourceID, + }, + DisplayName: "e621", + Domain: "e621.net", + Icon: "https://e621.icon", + } + + err = postgres.CreateSource(ctx, gormDB, source) + if err != nil { + t.Fatal(err) + } + + err = postgres.CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, "e66e6e6e6", "euser") + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + anthroveUserID models.AnthroveUserID + sourceID models.AnthroveSourceID + scrapeTime models.AnthroveScrapeTimeInterval + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid Data", + args: args{ + ctx: ctx, + anthroveUserID: validUserID, + sourceID: validSourceID, + scrapeTime: 10, + }, + wantErr: false, + }, + { + name: "Test 2: anthroveUserID to short", + args: args{ + ctx: ctx, + anthroveUserID: invalidUserID, + sourceID: validSourceID, + scrapeTime: 10, + }, + wantErr: true, + }, + { + name: "Test 3: anthroveUserID is empty", + args: args{ + ctx: ctx, + anthroveUserID: "", + sourceID: validSourceID, + scrapeTime: 10, + }, + wantErr: true, + }, + { + name: "Test 4: anthroveUserID to short", + args: args{ + ctx: ctx, + anthroveUserID: validUserID, + sourceID: "111", + scrapeTime: 10, + }, + wantErr: true, + }, + { + name: "Test 5: anthroveUserID is empty", + args: args{ + ctx: ctx, + anthroveUserID: validUserID, + sourceID: "", + scrapeTime: 10, + }, + wantErr: true, + }, + { + name: "Test 5: scrapeTime is empty", + args: args{ + ctx: ctx, + anthroveUserID: validUserID, + sourceID: validSourceID, + scrapeTime: 0, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.UpdateUserSourceScrapeTimeInterval(tt.args.ctx, tt.args.anthroveUserID, tt.args.sourceID, tt.args.scrapeTime); (err != nil) != tt.wantErr { + t.Errorf("UpdateUserSourceScrapeTimeInterval() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_postgresqlConnection_UpdateUserSourceLastScrapeTime(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + invalidUserID := models.AnthroveUserID("XXX") + + validSourceID := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source1")) + + validScrapeTime := models.AnthroveUserLastScrapeTime(time.Now()) + inValidScrapeTime := models.AnthroveUserLastScrapeTime{} + + source := &models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ + ID: validSourceID, + }, + DisplayName: "e621", + Domain: "e621.net", + Icon: "https://e621.icon", + } + + err = postgres.CreateSource(ctx, gormDB, source) + if err != nil { + t.Fatal(err) + } + + err = postgres.CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, "e66e6e6e6", "euser") + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + anthroveUserID models.AnthroveUserID + sourceID models.AnthroveSourceID + lastScrapeTime models.AnthroveUserLastScrapeTime + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid Data", + args: args{ + ctx: ctx, + anthroveUserID: validUserID, + sourceID: validSourceID, + lastScrapeTime: validScrapeTime, + }, + wantErr: false, + }, + { + name: "Test 2: anthroveUserID to short", + args: args{ + ctx: ctx, + anthroveUserID: invalidUserID, + sourceID: validSourceID, + lastScrapeTime: validScrapeTime, + }, + wantErr: true, + }, + { + name: "Test 3: anthroveUserID is empty", + args: args{ + ctx: ctx, + anthroveUserID: "", + sourceID: validSourceID, + lastScrapeTime: validScrapeTime, + }, + wantErr: true, + }, + { + name: "Test 4: anthroveUserID to short", + args: args{ + ctx: ctx, + anthroveUserID: validUserID, + sourceID: "111", + lastScrapeTime: validScrapeTime, + }, + wantErr: true, + }, + { + name: "Test 5: anthroveUserID is empty", + args: args{ + ctx: ctx, + anthroveUserID: validUserID, + sourceID: "", + lastScrapeTime: validScrapeTime, + }, + wantErr: true, + }, + { + name: "Test 5: scrapeTime is empty", + args: args{ + ctx: ctx, + anthroveUserID: validUserID, + sourceID: validSourceID, + lastScrapeTime: inValidScrapeTime, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.UpdateUserSourceLastScrapeTime(tt.args.ctx, tt.args.anthroveUserID, tt.args.sourceID, tt.args.lastScrapeTime); (err != nil) != tt.wantErr { + t.Errorf("UpdateUserSourceLastScrapeTime() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_postgresqlConnection_UpdateUserSourceValidation(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validUserID := models.AnthroveUserID(fmt.Sprintf("%025s", "User1")) + invalidUserID := models.AnthroveUserID("XXX") + + validSourceID := models.AnthroveSourceID(fmt.Sprintf("%025s", "Source1")) + + source := &models.Source{ + BaseModel: models.BaseModel[models.AnthroveSourceID]{ + ID: validSourceID, + }, + DisplayName: "e621", + Domain: "e621.net", + Icon: "https://e621.icon", + } + + err = postgres.CreateSource(ctx, gormDB, source) + if err != nil { + t.Fatal(err) + } + + err = postgres.CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, "e66e6e6e6", "euser") + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + anthroveUserID models.AnthroveUserID + sourceID models.AnthroveSourceID + valid bool + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid Data", + args: args{ + ctx: ctx, + anthroveUserID: validUserID, + sourceID: validSourceID, + valid: true, + }, + wantErr: false, + }, + { + name: "Test 2: anthroveUserID to short", + args: args{ + ctx: ctx, + anthroveUserID: invalidUserID, + sourceID: validSourceID, + valid: true, + }, + wantErr: true, + }, + { + name: "Test 3: anthroveUserID is empty", + args: args{ + ctx: ctx, + anthroveUserID: "", + sourceID: validSourceID, + valid: true, + }, + wantErr: true, + }, + { + name: "Test 4: anthroveUserID to short", + args: args{ + ctx: ctx, + anthroveUserID: validUserID, + sourceID: "111", + valid: true, + }, + wantErr: true, + }, + { + name: "Test 5: anthroveUserID is empty", + args: args{ + ctx: ctx, + anthroveUserID: validUserID, + sourceID: "", + valid: true, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.UpdateUserSourceValidation(tt.args.ctx, tt.args.anthroveUserID, tt.args.sourceID, tt.args.valid); (err != nil) != tt.wantErr { + t.Errorf("UpdateUserSourceValidation() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/error/validation.go b/pkg/error/validation.go index 889ae13..48b8632 100644 --- a/pkg/error/validation.go +++ b/pkg/error/validation.go @@ -3,8 +3,10 @@ package error import "fmt" const ( - AnthroveUserIDIsEmpty = "anthrovePostID cannot be empty" - AnthroveUserIDToShort = "anthrovePostID needs to be 25 characters long" + AnthroveUserIDIsEmpty = "anthrovePostID cannot be empty" + AnthroveUserIDToShort = "anthrovePostID needs to be 25 characters long" + AnthroveSourceIDEmpty = "anthroveSourceID cannot be empty" + AnthroveSourceIDToShort = "anthroveSourceID needs to be 25 characters long" ) type EntityValidationFailed struct { diff --git a/pkg/models/const.go b/pkg/models/const.go index 0e24228..00fc13b 100644 --- a/pkg/models/const.go +++ b/pkg/models/const.go @@ -1,5 +1,7 @@ package models +import "time" + type AnthroveUserID string type AnthrovePostID string type AnthroveSourceID string @@ -9,7 +11,7 @@ type AnthroveTagGroupName string type AnthroveTagAliasName string type AnthroveTagID string type AnthroveScrapeTimeInterval int -type AnthroveUserLastScrapeTime int +type AnthroveUserLastScrapeTime time.Time type Rating string type TagType string -- 2.45.1 From 3dfb345edc10bc28be6d6ba0fc16fa13804d4f01 Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 1 Jul 2024 14:14:17 +0200 Subject: [PATCH 119/124] fix: make sonarqube happy Signed-off-by: SoXX --- internal/postgres/tag.go | 8 ++++---- pkg/error/validation.go | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 4e851e2..405b5a8 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -97,7 +97,7 @@ func CreateTagAlias(ctx context.Context, db *gorm.DB, tagAliasName models.Anthro return &otterError.EntityValidationFailed{Reason: "tagAliasName cannot be empty"} } if tagID == "" { - return &otterError.EntityValidationFailed{Reason: "tagID cannot be empty"} + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveTagIDEmpty} } result := db.WithContext(ctx).Create(&models.TagAlias{ @@ -143,7 +143,7 @@ func GetAllTagAliasByTag(ctx context.Context, db *gorm.DB, tagID models.Anthrove var tagAliases []models.TagAlias if tagID == "" { - return nil, &otterError.EntityValidationFailed{Reason: "tagID cannot be empty"} + return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveTagIDEmpty} } result := db.WithContext(ctx).Where("tag_id = ?", tagID).Find(&tagAliases) @@ -191,7 +191,7 @@ func CreateTagGroup(ctx context.Context, db *gorm.DB, tagGroupName models.Anthro return &otterError.EntityValidationFailed{Reason: "tagGroupName cannot be empty"} } if tagID == "" { - return &otterError.EntityValidationFailed{Reason: "tagID cannot be empty"} + return &otterError.EntityValidationFailed{Reason: otterError.AnthroveTagIDEmpty} } result := db.WithContext(ctx).Create(&models.TagGroup{ @@ -237,7 +237,7 @@ func GetAllTagGroupByTag(ctx context.Context, db *gorm.DB, tagID models.Anthrove var tagGroups []models.TagGroup if tagID == "" { - return nil, &otterError.EntityValidationFailed{Reason: "tagID cannot be empty"} + return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveTagIDEmpty} } result := db.WithContext(ctx).Where("tag_id = ?", tagID).Find(&tagGroups) diff --git a/pkg/error/validation.go b/pkg/error/validation.go index 48b8632..27ec3c4 100644 --- a/pkg/error/validation.go +++ b/pkg/error/validation.go @@ -7,6 +7,7 @@ const ( AnthroveUserIDToShort = "anthrovePostID needs to be 25 characters long" AnthroveSourceIDEmpty = "anthroveSourceID cannot be empty" AnthroveSourceIDToShort = "anthroveSourceID needs to be 25 characters long" + AnthroveTagIDEmpty = "tagID cannot be empty" ) type EntityValidationFailed struct { -- 2.45.1 From 47fda2994ba528a420836de04d26d7b73e73e9a5 Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 1 Jul 2024 21:38:09 +0200 Subject: [PATCH 120/124] fix: fixed issues in PR Signed-off-by: SoXX --- internal/postgres/post.go | 2 +- internal/postgres/post_test.go | 6 +++--- pkg/database/postgres.go | 16 ++++++++++++---- pkg/database/postgres_test.go | 4 ++-- pkg/models/api.go | 5 +++++ pkg/models/userFavorite.go | 4 ---- 6 files changed, 23 insertions(+), 14 deletions(-) create mode 100644 pkg/models/api.go diff --git a/internal/postgres/post.go b/internal/postgres/post.go index 3679132..6c08cf3 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -59,7 +59,7 @@ func GetPostByAnthroveID(ctx context.Context, db *gorm.DB, anthrovePostID models return &post, nil } -func GetPostByURL(ctx context.Context, db *gorm.DB, sourceURL string) (*models.Post, error) { +func GetPostBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (*models.Post, error) { if sourceURL == "" { return nil, &otterError.EntityValidationFailed{Reason: "sourceURL is not set"} diff --git a/internal/postgres/post_test.go b/internal/postgres/post_test.go index f679eaa..bb525c8 100644 --- a/internal/postgres/post_test.go +++ b/internal/postgres/post_test.go @@ -249,13 +249,13 @@ func TestGetPostBySourceURL(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := GetPostByURL(tt.args.ctx, tt.args.db, tt.args.sourceURL) + got, err := GetPostBySourceURL(tt.args.ctx, tt.args.db, tt.args.sourceURL) if (err != nil) != tt.wantErr { - t.Errorf("GetPostByURL() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetPostBySourceURL() error = %v, wantErr %v", err, tt.wantErr) return } if !checkPost(got, tt.want) { - t.Errorf("GetPostByURL() got = %v, want %v", got, tt.want) + t.Errorf("GetPostBySourceURL() got = %v, want %v", got, tt.want) } }) } diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 6d3dd07..90080c0 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -15,7 +15,7 @@ import ( log "github.com/sirupsen/logrus" gormPostgres "gorm.io/driver/postgres" "gorm.io/gorm" - logger2 "gorm.io/gorm/logger" + gormLogger "gorm.io/gorm/logger" ) //go:embed migrations/*.sql @@ -34,6 +34,8 @@ func NewPostgresqlConnection() OtterSpace { func (p *postgresqlConnection) Connect(_ context.Context, config models.DatabaseConfig) error { var localSSL string + var logLevel gormLogger.LogLevel + if config.SSL { localSSL = "require" } else { @@ -45,9 +47,15 @@ func (p *postgresqlConnection) Connect(_ context.Context, config models.Database dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s TimeZone=%s", config.Endpoint, config.Username, config.Password, config.Database, config.Port, localSSL, config.Timezone) var err error - dbLogger := logger2.New(log2.New(os.Stdout, "\r\n", log2.LstdFlags), logger2.Config{ + if p.debug { + logLevel = gormLogger.Info + } else { + logLevel = gormLogger.Silent + } + + dbLogger := gormLogger.New(log2.New(os.Stdout, "\r\n", log2.LstdFlags), gormLogger.Config{ SlowThreshold: 200 * time.Millisecond, - LogLevel: logger2.Info, + LogLevel: logLevel, IgnoreRecordNotFoundError: true, Colorful: true, }) @@ -105,7 +113,7 @@ func (p *postgresqlConnection) GetPostByAnthroveID(ctx context.Context, anthrove } func (p *postgresqlConnection) GetPostByURL(ctx context.Context, sourceUrl string) (*models.Post, error) { - return postgres.GetPostByURL(ctx, p.db, sourceUrl) + return postgres.GetPostBySourceURL(ctx, p.db, sourceUrl) } func (p *postgresqlConnection) GetPostBySourceID(ctx context.Context, sourceID models.AnthroveSourceID) (*models.Post, error) { diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index 93534cc..41af09f 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -887,11 +887,11 @@ func Test_postgresqlConnection_GetPostByURL(t *testing.T) { } got, err := p.GetPostByURL(tt.args.ctx, tt.args.sourceUrl) if (err != nil) != tt.wantErr { - t.Errorf("GetPostByURL() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("GetPostBySourceURL() error = %v, wantErr %v", err, tt.wantErr) return } if !checkPost(got, tt.want) { - t.Errorf("GetPostByURL() got = %v, want %v", got, tt.want) + t.Errorf("GetPostBySourceURL() got = %v, want %v", got, tt.want) } }) } diff --git a/pkg/models/api.go b/pkg/models/api.go new file mode 100644 index 0000000..37adbd0 --- /dev/null +++ b/pkg/models/api.go @@ -0,0 +1,5 @@ +package models + +type FavoriteList struct { + Posts []Post `json:"posts,omitempty"` +} diff --git a/pkg/models/userFavorite.go b/pkg/models/userFavorite.go index 3bebe91..028b907 100644 --- a/pkg/models/userFavorite.go +++ b/pkg/models/userFavorite.go @@ -11,7 +11,3 @@ type UserFavorites struct { func (UserFavorites) TableName() string { return "UserFavorites" } - -type FavoriteList struct { - Posts []Post `json:"posts,omitempty"` -} -- 2.45.1 From 1b40c6145a798deb39cd77f82ff41a5170fbea59 Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 1 Jul 2024 22:06:36 +0200 Subject: [PATCH 121/124] refactor: changed CreateTag to align with other functions Signed-off-by: SoXX --- internal/postgres/tag.go | 16 +++++++----- internal/postgres/tag_test.go | 48 +++++++++++++++++++---------------- pkg/database/database.go | 3 +++ pkg/database/postgres.go | 14 ++++++++++ pkg/database/postgres_test.go | 18 ++++++------- pkg/database/tag.go | 6 +++++ pkg/models/const.go | 1 + 7 files changed, 69 insertions(+), 37 deletions(-) diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 405b5a8..bc5ccd0 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -10,13 +10,17 @@ import ( "gorm.io/gorm" ) -func CreateTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { +func CreateTag(ctx context.Context, db *gorm.DB, tagName models.AnthroveTagName, tagType models.TagType) error { - if tag == nil { - return &otterError.EntityValidationFailed{Reason: "Tag is nil"} + if tagName == "" { + return &otterError.EntityValidationFailed{Reason: "tagName is empty"} } - result := db.WithContext(ctx).Create(tag) + if tagType == "" { + return &otterError.EntityValidationFailed{Reason: "tagType is empty"} + } + + result := db.WithContext(ctx).Create(&models.Tag{Name: string(tagName), Type: tagType}) if result.Error != nil { if errors.Is(result.Error, gorm.ErrDuplicatedKey) { return &otterError.EntityAlreadyExists{} @@ -29,8 +33,8 @@ func CreateTag(ctx context.Context, db *gorm.DB, tag *models.Tag) error { } log.WithFields(log.Fields{ - "tag_name": tag.Name, - "tag_type": tag.Type, + "tag_name": tagName, + "tag_type": tagType, }).Trace("database: created tag node") return nil diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index adbc867..5a30658 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -128,7 +128,7 @@ func TestGetTags(t *testing.T) { } for _, tag := range tags { - err = CreateTag(ctx, gormDB, &tag) + err = CreateTag(ctx, gormDB, models.AnthroveTagName(tag.Name), tag.Type) if err != nil { t.Fatal(err) } @@ -202,9 +202,10 @@ func TestCreateTag(t *testing.T) { // Test type args struct { - ctx context.Context - db *gorm.DB - tag *models.Tag + ctx context.Context + db *gorm.DB + tagName models.AnthroveTagName + tagType models.TagType } tests := []struct { name string @@ -214,34 +215,37 @@ func TestCreateTag(t *testing.T) { { name: "Test 1: Valid Tag", args: args{ - ctx: ctx, - db: gormDB, - tag: &validTag, + ctx: ctx, + db: gormDB, + tagName: models.AnthroveTagName(validTag.Name), + tagType: validTag.Type, }, wantErr: false, }, { name: "Test 2: Duplicate Tag", args: args{ - ctx: ctx, - db: gormDB, - tag: &validTag, + ctx: ctx, + db: gormDB, + tagName: models.AnthroveTagName(validTag.Name), + tagType: validTag.Type, }, wantErr: true, }, { name: "Test 3: Invalid Tag", args: args{ - ctx: ctx, - db: gormDB, - tag: &invalidTag, + ctx: ctx, + db: gormDB, + tagName: models.AnthroveTagName(invalidTag.Name), + tagType: invalidTag.Type, }, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := CreateTag(tt.args.ctx, tt.args.db, tt.args.tag); (err != nil) != tt.wantErr { + if err := CreateTag(tt.args.ctx, tt.args.db, tt.args.tagName, tt.args.tagType); (err != nil) != tt.wantErr { t.Errorf("CreateTag() error = %v, wantErr %v", err, tt.wantErr) } }) @@ -269,7 +273,7 @@ func TestCreateTagAlias(t *testing.T) { Type: models.Character, } - err = CreateTag(ctx, gormDB, validTag) + err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } @@ -379,7 +383,7 @@ func TestGetAllTagAlias(t *testing.T) { }, } - err = CreateTag(ctx, gormDB, validTag) + err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } @@ -456,7 +460,7 @@ func TestGetAllTagAliasByTag(t *testing.T) { }, } - err = CreateTag(ctx, gormDB, validTag) + err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } @@ -540,7 +544,7 @@ func TestDeleteTagAlias(t *testing.T) { Type: models.Character, } - err = CreateTag(ctx, gormDB, validTag) + err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } @@ -618,7 +622,7 @@ func TestCreateTagGroup(t *testing.T) { Type: models.Character, } - err = CreateTag(ctx, gormDB, validTag) + err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } @@ -728,7 +732,7 @@ func TestGetAllTagGroup(t *testing.T) { }, } - err = CreateTag(ctx, gormDB, validTag) + err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } @@ -805,7 +809,7 @@ func TestGetAllTagGroupByTag(t *testing.T) { }, } - err = CreateTag(ctx, gormDB, validTag) + err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } @@ -889,7 +893,7 @@ func TestDeleteTagGroup(t *testing.T) { Type: models.Character, } - err = CreateTag(ctx, gormDB, validTag) + err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } diff --git a/pkg/database/database.go b/pkg/database/database.go index 0bce2bf..bc19286 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -19,6 +19,9 @@ type OtterSpace interface { // Source contains all function that are needed to manage the Source Source + // Tag contains all functions that are used to manage Tag + Tag + // TagAlias contains all function that are needed to manage the TagAlias TagAlias diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 90080c0..4e1b02b 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -202,6 +202,20 @@ func (p *postgresqlConnection) DeleteTagGroup(ctx context.Context, tagGroupName return postgres.DeleteTagGroup(ctx, p.db, tagGroupName) } +func (p *postgresqlConnection) CreateTag(ctx context.Context, tagName models.AnthroveTagName, tagType models.TagType) error { + return postgres.CreateTag(ctx, p.db, tagName, tagType) +} + +func (p *postgresqlConnection) GetAllTagByTagType(ctx context.Context, tagType models.TagType) ([]models.Tag, error) { + //TODO implement me + panic("implement me") +} + +func (p *postgresqlConnection) DeleteTag(ctx context.Context, tagName models.AnthroveTagName) error { + //TODO implement me + panic("implement me") +} + // HELPER func (p *postgresqlConnection) migrateDatabase(dbPool *gorm.DB) error { diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index 41af09f..3a46606 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -1704,7 +1704,7 @@ func Test_postgresqlConnection_GetAllTags(t *testing.T) { } for _, tag := range tags { - err = postgres.CreateTag(ctx, gormDB, &tag) + err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(tag.Name), tag.Type) if err != nil { t.Fatal(err) } @@ -2043,7 +2043,7 @@ func Test_postgresqlConnection_CreateTagAlias(t *testing.T) { Type: models.Character, } - err = postgres.CreateTag(ctx, gormDB, validTag) + err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } @@ -2151,7 +2151,7 @@ func Test_postgresqlConnection_GetAllTagAlias(t *testing.T) { }, } - err = postgres.CreateTag(ctx, gormDB, validTag) + err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } @@ -2228,7 +2228,7 @@ func Test_postgresqlConnection_GetAllTagAliasByTag(t *testing.T) { }, } - err = postgres.CreateTag(ctx, gormDB, validTag) + err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } @@ -2312,7 +2312,7 @@ func Test_postgresqlConnection_DeleteTagAlias(t *testing.T) { Type: models.Character, } - err = postgres.CreateTag(ctx, gormDB, validTag) + err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } @@ -2392,7 +2392,7 @@ func Test_postgresqlConnection_CreateTagGroup(t *testing.T) { Type: models.Character, } - err = postgres.CreateTag(ctx, gormDB, validTag) + err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } @@ -2500,7 +2500,7 @@ func Test_postgresqlConnection_GetAllTagGroup(t *testing.T) { }, } - err = postgres.CreateTag(ctx, gormDB, validTag) + err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } @@ -2577,7 +2577,7 @@ func Test_postgresqlConnection_GetAllTagGroupByTag(t *testing.T) { }, } - err = postgres.CreateTag(ctx, gormDB, validTag) + err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } @@ -2661,7 +2661,7 @@ func Test_postgresqlConnection_DeleteTagGroup(t *testing.T) { Type: models.Character, } - err = postgres.CreateTag(ctx, gormDB, validTag) + err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) if err != nil { t.Fatal(err) } diff --git a/pkg/database/tag.go b/pkg/database/tag.go index eb0f4a5..ecaf3d5 100644 --- a/pkg/database/tag.go +++ b/pkg/database/tag.go @@ -7,6 +7,12 @@ import ( ) type Tag interface { + CreateTag(ctx context.Context, tagName models.AnthroveTagName, tagType models.TagType) error + // GetAllTags retrieves all tags. GetAllTags(ctx context.Context) ([]models.Tag, error) + + GetAllTagByTagType(ctx context.Context, tagType models.TagType) ([]models.Tag, error) + + DeleteTag(ctx context.Context, tagName models.AnthroveTagName) error } diff --git a/pkg/models/const.go b/pkg/models/const.go index 00fc13b..7e84b0c 100644 --- a/pkg/models/const.go +++ b/pkg/models/const.go @@ -12,6 +12,7 @@ type AnthroveTagAliasName string type AnthroveTagID string type AnthroveScrapeTimeInterval int type AnthroveUserLastScrapeTime time.Time +type AnthroveTagName string type Rating string type TagType string -- 2.45.1 From a842d64f1cb2f39529f64bc5fd6ffde0fabc1b8b Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 1 Jul 2024 22:15:43 +0200 Subject: [PATCH 122/124] refactor: added deletion of tags Signed-off-by: SoXX --- internal/postgres/tag.go | 26 ++++++++++++- internal/postgres/tag_test.go | 70 +++++++++++++++++++++++++++++++++++ pkg/database/postgres.go | 3 +- pkg/database/postgres_test.go | 70 +++++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 4 deletions(-) diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index bc5ccd0..f810266 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -13,11 +13,11 @@ import ( func CreateTag(ctx context.Context, db *gorm.DB, tagName models.AnthroveTagName, tagType models.TagType) error { if tagName == "" { - return &otterError.EntityValidationFailed{Reason: "tagName is empty"} + return &otterError.EntityValidationFailed{Reason: "tagName cannot be empty"} } if tagType == "" { - return &otterError.EntityValidationFailed{Reason: "tagType is empty"} + return &otterError.EntityValidationFailed{Reason: "tagType cannot be empty"} } result := db.WithContext(ctx).Create(&models.Tag{Name: string(tagName), Type: tagType}) @@ -40,6 +40,28 @@ func CreateTag(ctx context.Context, db *gorm.DB, tagName models.AnthroveTagName, return nil } +func DeleteTag(ctx context.Context, db *gorm.DB, tagName models.AnthroveTagName) error { + + if tagName == "" { + return &otterError.EntityValidationFailed{Reason: "tagName cannot be empty"} + } + + result := db.WithContext(ctx).Delete(&models.Tag{Name: string(tagName)}) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return &otterError.NoDataFound{} + } + return result.Error + } + + log.WithFields(log.Fields{ + "tag_name": tagName, + }).Trace("database: deleted tag") + + return nil +} + func CreateTagAndReferenceToPost(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, tag *models.Tag) error { if anthrovePostID == "" { diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index 5a30658..88eabcd 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -949,3 +949,73 @@ func TestDeleteTagGroup(t *testing.T) { }) } } + +func TestDeleteTag(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validTagID := models.AnthroveTagID("toothless") + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + err = CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + tagName models.AnthroveTagName + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid TagName", + args: args{ + ctx: ctx, + db: gormDB, + tagName: models.AnthroveTagName(validTagID), + }, + wantErr: false, + }, + { + name: "Test 2: Invalid TagName", + args: args{ + ctx: ctx, + db: gormDB, + tagName: models.AnthroveTagName("aaa"), + }, + wantErr: false, + }, + { + name: "Test 3: No TagName", + args: args{ + ctx: ctx, + db: gormDB, + tagName: "", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := DeleteTag(tt.args.ctx, tt.args.db, tt.args.tagName); (err != nil) != tt.wantErr { + t.Errorf("DeleteTag() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 4e1b02b..0acb71e 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -212,8 +212,7 @@ func (p *postgresqlConnection) GetAllTagByTagType(ctx context.Context, tagType m } func (p *postgresqlConnection) DeleteTag(ctx context.Context, tagName models.AnthroveTagName) error { - //TODO implement me - panic("implement me") + return postgres.DeleteTag(ctx, p.db, tagName) } // HELPER diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index 3a46606..88b10ba 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -3073,3 +3073,73 @@ func Test_postgresqlConnection_UpdateUserSourceValidation(t *testing.T) { }) } } + +func Test_postgresqlConnection_DeleteTag(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + validTagID := models.AnthroveTagID("toothless") + + validTag := &models.Tag{ + Name: string(validTagID), + Type: models.Character, + } + + err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(validTag.Name), validTag.Type) + if err != nil { + t.Fatal(err) + } + + // Test + type args struct { + ctx context.Context + tagName models.AnthroveTagName + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid TagName", + args: args{ + ctx: ctx, + tagName: models.AnthroveTagName(validTagID), + }, + wantErr: false, + }, + { + name: "Test 2: Invalid TagName", + args: args{ + ctx: ctx, + tagName: models.AnthroveTagName("aaa"), + }, + wantErr: false, + }, + { + name: "Test 3: No TagName", + args: args{ + ctx: ctx, + tagName: "", + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.DeleteTag(tt.args.ctx, tt.args.tagName); (err != nil) != tt.wantErr { + t.Errorf("DeleteTag() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} -- 2.45.1 From 2d4102be6ab0e5599bfdaf113406d39cba21c704 Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 1 Jul 2024 22:29:37 +0200 Subject: [PATCH 123/124] refactor: added getting of tag by specific type Signed-off-by: SoXX --- internal/postgres/tag.go | 23 +++++++++ internal/postgres/tag_test.go | 94 +++++++++++++++++++++++++++++++++++ pkg/database/postgres.go | 5 +- pkg/database/postgres_test.go | 94 +++++++++++++++++++++++++++++++++++ pkg/database/tag.go | 2 +- 5 files changed, 214 insertions(+), 4 deletions(-) diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index f810266..6b963f7 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -62,6 +62,29 @@ func DeleteTag(ctx context.Context, db *gorm.DB, tagName models.AnthroveTagName) return nil } +func GetAllTagByTagsType(ctx context.Context, db *gorm.DB, tagType models.TagType) ([]models.Tag, error) { + var tags []models.Tag + + if tagType == "" { + return nil, &otterError.EntityValidationFailed{Reason: "tagType cannot be empty"} + } + + result := db.WithContext(ctx).Find(&tags).Where("tag_type = ?", tagType) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, &otterError.NoDataFound{} + } + return nil, result.Error + } + + log.WithFields(log.Fields{ + "tags_length": len(tags), + }).Trace("database: got tag") + + return tags, nil +} + func CreateTagAndReferenceToPost(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID, tag *models.Tag) error { if anthrovePostID == "" { diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index 88eabcd..a976bd4 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -1019,3 +1019,97 @@ func TestDeleteTag(t *testing.T) { }) } } + +func TestGetAllTagByTagType(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validTags := []models.Tag{ + { + Name: "JayTheFerret", + Type: models.Character, + }, + { + Name: "SoXX", + Type: models.Character, + }, + { + Name: "Alphyron", + Type: models.Character, + }, + { + Name: "Dragon", + Type: models.Species, + }, + } + + for _, tag := range validTags { + err = CreateTag(ctx, gormDB, models.AnthroveTagName(tag.Name), tag.Type) + if err != nil { + t.Fatal(err) + } + } + + // Test + type args struct { + ctx context.Context + db *gorm.DB + tagType models.TagType + } + tests := []struct { + name string + args args + want []models.Tag + wantErr bool + }{ + { + name: "Test 1: Get Data", + args: args{ + ctx: ctx, + db: gormDB, + tagType: models.Character, + }, + want: validTags, + wantErr: false, + }, + { + name: "Test 2: invalid Tag Type", + args: args{ + ctx: ctx, + db: gormDB, + tagType: "aa", + }, + want: validTags, + wantErr: false, + }, + { + name: "Test 3: No Tag Type", + args: args{ + ctx: ctx, + db: gormDB, + tagType: "", + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetAllTagByTagsType(tt.args.ctx, tt.args.db, tt.args.tagType) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllTagByTagsType() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !checkTag(got, tt.want) { + t.Errorf("GetAllTagByTagsType() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 0acb71e..2692907 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -206,9 +206,8 @@ func (p *postgresqlConnection) CreateTag(ctx context.Context, tagName models.Ant return postgres.CreateTag(ctx, p.db, tagName, tagType) } -func (p *postgresqlConnection) GetAllTagByTagType(ctx context.Context, tagType models.TagType) ([]models.Tag, error) { - //TODO implement me - panic("implement me") +func (p *postgresqlConnection) GetAllTagsByTagType(ctx context.Context, tagType models.TagType) ([]models.Tag, error) { + return postgres.GetAllTagByTagsType(ctx, p.db, tagType) } func (p *postgresqlConnection) DeleteTag(ctx context.Context, tagName models.AnthroveTagName) error { diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index 88b10ba..f00602e 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -3143,3 +3143,97 @@ func Test_postgresqlConnection_DeleteTag(t *testing.T) { }) } } + +func Test_postgresqlConnection_GetAllTagsByTagType(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + + validTags := []models.Tag{ + { + Name: "JayTheFerret", + Type: models.Character, + }, + { + Name: "SoXX", + Type: models.Character, + }, + { + Name: "Alphyron", + Type: models.Character, + }, + { + Name: "Dragon", + Type: models.Species, + }, + } + + for _, tag := range validTags { + err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(tag.Name), tag.Type) + if err != nil { + t.Fatal(err) + } + } + + // Test + type args struct { + ctx context.Context + tagType models.TagType + } + tests := []struct { + name string + args args + want []models.Tag + wantErr bool + }{ + { + name: "Test 1: Get Data", + args: args{ + ctx: ctx, + tagType: models.Character, + }, + want: validTags, + wantErr: false, + }, + { + name: "Test 2: invalid Tag Type", + args: args{ + ctx: ctx, + tagType: "aa", + }, + want: validTags, + wantErr: false, + }, + { + name: "Test 3: No Tag Type", + args: args{ + ctx: ctx, + tagType: "", + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + got, err := p.GetAllTagsByTagType(tt.args.ctx, tt.args.tagType) + if (err != nil) != tt.wantErr { + t.Errorf("GetAllTagsByTagType() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetAllTagsByTagType() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/database/tag.go b/pkg/database/tag.go index ecaf3d5..44fa553 100644 --- a/pkg/database/tag.go +++ b/pkg/database/tag.go @@ -12,7 +12,7 @@ type Tag interface { // GetAllTags retrieves all tags. GetAllTags(ctx context.Context) ([]models.Tag, error) - GetAllTagByTagType(ctx context.Context, tagType models.TagType) ([]models.Tag, error) + GetAllTagsByTagType(ctx context.Context, tagType models.TagType) ([]models.Tag, error) DeleteTag(ctx context.Context, tagName models.AnthroveTagName) error } -- 2.45.1 From 768203ebd7ec5ab7c3b89676c2a2c5dd2c460bd0 Mon Sep 17 00:00:00 2001 From: SoXX Date: Mon, 1 Jul 2024 22:40:53 +0200 Subject: [PATCH 124/124] fix: fixed function to work properly Signed-off-by: SoXX --- internal/postgres/tag.go | 2 +- internal/postgres/tag_test.go | 17 ++++++++++++++++- pkg/database/postgres_test.go | 17 ++++++++++++++++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go index 6b963f7..7ca240c 100644 --- a/internal/postgres/tag.go +++ b/internal/postgres/tag.go @@ -69,7 +69,7 @@ func GetAllTagByTagsType(ctx context.Context, db *gorm.DB, tagType models.TagTyp return nil, &otterError.EntityValidationFailed{Reason: "tagType cannot be empty"} } - result := db.WithContext(ctx).Find(&tags).Where("tag_type = ?", tagType) + result := db.WithContext(ctx).Model(&models.Tag{}).Where("tag_type = ?", tagType).Scan(&tags) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { diff --git a/internal/postgres/tag_test.go b/internal/postgres/tag_test.go index a976bd4..ab15604 100644 --- a/internal/postgres/tag_test.go +++ b/internal/postgres/tag_test.go @@ -1050,6 +1050,21 @@ func TestGetAllTagByTagType(t *testing.T) { }, } + expectetResult := []models.Tag{ + { + Name: "JayTheFerret", + Type: models.Character, + }, + { + Name: "SoXX", + Type: models.Character, + }, + { + Name: "Alphyron", + Type: models.Character, + }, + } + for _, tag := range validTags { err = CreateTag(ctx, gormDB, models.AnthroveTagName(tag.Name), tag.Type) if err != nil { @@ -1076,7 +1091,7 @@ func TestGetAllTagByTagType(t *testing.T) { db: gormDB, tagType: models.Character, }, - want: validTags, + want: expectetResult, wantErr: false, }, { diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index f00602e..56e2036 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -3174,6 +3174,21 @@ func Test_postgresqlConnection_GetAllTagsByTagType(t *testing.T) { }, } + expectetResult := []models.Tag{ + { + Name: "JayTheFerret", + Type: models.Character, + }, + { + Name: "SoXX", + Type: models.Character, + }, + { + Name: "Alphyron", + Type: models.Character, + }, + } + for _, tag := range validTags { err = postgres.CreateTag(ctx, gormDB, models.AnthroveTagName(tag.Name), tag.Type) if err != nil { @@ -3198,7 +3213,7 @@ func Test_postgresqlConnection_GetAllTagsByTagType(t *testing.T) { ctx: ctx, tagType: models.Character, }, - want: validTags, + want: expectetResult, wantErr: false, }, { -- 2.45.1