Compare commits

..

No commits in common. "b5437ecc6298c3da5d807f3082ac784d8000ddc0" and "9c8a7c1e16fdf7ab6a887282ef93f8fc85ae4237" have entirely different histories.

18 changed files with 213 additions and 383 deletions

View File

@ -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("CheckIfUserHasPostAsFavorite() error = %v, wantErr %v", err, tt.wantErr)
t.Errorf("CheckReferenceBetweenUserAndPost() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("CheckIfUserHasPostAsFavorite() got = %v, want %v", got, tt.want)
t.Errorf("CheckReferenceBetweenUserAndPost() 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("CheckIfUserHasPostAsFavorite() error = %v, wantErr %v", err, tt.wantErr)
t.Errorf("CheckReferenceBetweenUserAndPost() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("CheckIfUserHasPostAsFavorite() got = %v, want %v", got, tt.want)
t.Errorf("CheckReferenceBetweenUserAndPost() got = %v, want %v", got, tt.want)
}
})
}

View File

@ -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("CreatePostWithReferenceToTagAnd() error = %v, wantErr %v", err, tt.wantErr)
t.Errorf("CreateTagAndReferenceToPost() error = %v, wantErr %v", err, tt.wantErr)
}
})
}

View File

@ -6,7 +6,6 @@ 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"
)
@ -57,21 +56,15 @@ 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, account_validate, account_validation_key)
SELECT $2, source.id, $3, $4, false, $5
INSERT INTO "UserSource" (user_id, source_id, account_username, account_id)
SELECT $2, source.id, $3, $4
FROM "Source" AS source
WHERE source.id = $6;`, anthroveUserID, anthroveUserID, accountUsername, accountId, validationCode, sourceID)
WHERE source.id = $5;`, anthroveUserID, anthroveUserID, accountUsername, accountId, sourceID)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrDuplicatedKey) {
@ -169,8 +162,9 @@ 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) (*models.UserSource, error) {
var userSource models.UserSource
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)
if anthroveUserID == "" {
return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty}
@ -188,7 +182,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(&userSources)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, &otterError.NoDataFound{}
@ -196,16 +190,38 @@ 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 &userSource, nil
return userSourceMap, nil
}
func GetAllUsers(ctx context.Context, db *gorm.DB) ([]models.User, error) {
func GetAllAnthroveUserIDs(ctx context.Context, db *gorm.DB) ([]models.AnthroveUserID, error) {
var users []models.User
var userIDs []models.AnthroveUserID
result := db.WithContext(ctx).Model(&models.User{}).Find(&users)
if result.Error != nil {
@ -215,11 +231,15 @@ func GetAllUsers(ctx context.Context, db *gorm.DB) ([]models.User, error) {
return nil, result.Error
}
for _, user := range users {
userIDs = append(userIDs, user.ID)
}
log.WithFields(log.Fields{
"anthrove_user_id_count": len(users),
"anthrove_user_id_count": len(userIDs),
}).Trace("database: got all anthrove user IDs")
return users, nil
return userIDs, nil
}
func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) {

View File

@ -198,7 +198,7 @@ func TestCreateUserNodeWithSourceRelation(t *testing.T) {
}
}
func TestGetAllUsers(t *testing.T) {
func TestGetAllAnthroveUserIDs(t *testing.T) {
// Setup trow away container
ctx := context.Background()
container, gormDB, err := test.StartPostgresContainer(ctx)
@ -212,20 +212,10 @@ func TestGetAllUsers(t *testing.T) {
validUserID02 := models.AnthroveUserID(fmt.Sprintf("%025s", "User2"))
validUserID03 := models.AnthroveUserID(fmt.Sprintf("%025s", "User3"))
users := []models.User{
{
BaseModel: models.BaseModel[models.AnthroveUserID]{ID: validUserID01},
},
{
BaseModel: models.BaseModel[models.AnthroveUserID]{ID: validUserID02},
},
{
BaseModel: models.BaseModel[models.AnthroveUserID]{ID: validUserID03},
},
}
users := []models.AnthroveUserID{validUserID01, validUserID02, validUserID03}
for _, user := range users {
err = CreateUser(ctx, gormDB, user.ID)
err = CreateUser(ctx, gormDB, user)
if err != nil {
t.Fatal(err)
}
@ -239,7 +229,7 @@ func TestGetAllUsers(t *testing.T) {
tests := []struct {
name string
args args
want []models.User
want []models.AnthroveUserID
wantErr bool
}{
{
@ -254,13 +244,13 @@ func TestGetAllUsers(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := GetAllUsers(tt.args.ctx, tt.args.db)
got, err := GetAllAnthroveUserIDs(tt.args.ctx, tt.args.db)
if (err != nil) != tt.wantErr {
t.Errorf("GetAllUsers() error = %v, wantErr %v", err, tt.wantErr)
t.Errorf("GetAllAnthroveUserIDs() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !checkUser(got, tt.want) {
t.Errorf("GetAllUsers() got = %v, want %v", got, tt.want)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("GetAllAnthroveUserIDs() got = %v, want %v", got, tt.want)
}
})
}
@ -288,14 +278,13 @@ func TestGetUserSourceBySourceID(t *testing.T) {
},
DisplayName: "e621",
Domain: "e621.net",
Icon: "https://e621.icon",
}
expectedResult := &models.UserSource{
UserID: string(validUserID),
expectedResult := make(map[string]models.UserSource)
expectedResult["e621"] = models.UserSource{
UserID: "e1",
AccountUsername: "euser",
Source: models.Source{
BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: source.ID},
DisplayName: source.DisplayName,
Domain: source.Domain,
Icon: source.Icon,
@ -307,7 +296,7 @@ func TestGetUserSourceBySourceID(t *testing.T) {
t.Fatal(err)
}
err = CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, expectedResult.UserID, expectedResult.AccountUsername)
err = CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername)
if err != nil {
t.Fatal(err)
}
@ -322,7 +311,7 @@ func TestGetUserSourceBySourceID(t *testing.T) {
tests := []struct {
name string
args args
want *models.UserSource
want map[string]models.UserSource
wantErr bool
}{
{
@ -411,7 +400,7 @@ func TestGetUserSourceBySourceID(t *testing.T) {
t.Errorf("GetUserSourceBySourceID() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !checkUserSource(got, tt.want) {
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("GetUserSourceBySourceID() got = %v, want %v", got, tt.want)
}
})
@ -569,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("GetAllUserFavoritesWithPagination() 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("GetAllUserFavoritesWithPagination() got = %v, want %v", got, tt.want)
t.Errorf("GetUserFavoriteWithPagination() got = %v, want %v", got, tt.want)
}
})
}
@ -809,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("GetAllUserSources() 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("GetAllUserSources() got = %v, want %v", got, tt.want)
t.Errorf("GetUserSourceLinks() got = %v, want %v", got, tt.want)
}
})
}
@ -941,48 +930,12 @@ 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("GetAllTagsFromUser() 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("GetAllTagsFromUser() got = %v, want %v", got, tt.want)
t.Errorf("GetUserTagWitRelationToFavedPosts() got = %v, want %v", got, tt.want)
}
})
}
}
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
}

View File

@ -2,7 +2,6 @@ package database
import (
"context"
"git.dragse.it/anthrove/otter-space-sdk/pkg/models"
)
@ -10,18 +9,72 @@ 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
// 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 contains all function that are needed to manage the AnthroveUser
User
// CreateSource adds a new source to the database.
CreateSource(ctx context.Context, anthroveSource *models.Source) error
// Source contains all function that are needed to manage the Source
Source
// CreatePost adds a new post to the database.
CreatePost(ctx context.Context, anthrovePost *models.Post) error
// TagAlias contains all function that are needed to manage the TagAlias
TagAlias
// CreateTagAndReferenceToPost adds a tag with a relation to a post.
CreateTagAndReferenceToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error
// TagGroup contains all function that are needed to manage the TagGroup
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
UpdateUserWithScrapeTimeInterval(ctx context.Context, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, scrapeTime models.AnthroveScrapeTimeInterval) error
}

View File

@ -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,14 +89,11 @@ CREATE TABLE "UserFavorites"
CREATE TABLE "UserSource"
(
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),
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 (source_id, account_username, account_id)
);
@ -106,4 +103,17 @@ 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;

View File

@ -1,28 +0,0 @@
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)
// CreatePostWithReferenceToTagAnd adds a tag with a relation to a post.
CreatePostWithReferenceToTagAnd(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) 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
}

View File

@ -84,11 +84,11 @@ func (p *postgresqlConnection) CreatePost(ctx context.Context, anthrovePost *mod
return postgres.CreatePost(ctx, p.db, anthrovePost)
}
func (p *postgresqlConnection) CreatePostWithReferenceToTagAnd(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *models.Tag) error {
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) CreatePostReference(ctx context.Context, anthrovePostID models.AnthrovePostID, sourceDomain models.AnthroveSourceDomain, postURL models.AnthrovePostURL, config models.PostReferenceConfig) error {
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)
}
@ -96,7 +96,7 @@ func (p *postgresqlConnection) CreateReferenceBetweenUserAndPost(ctx context.Con
return postgres.CreateReferenceBetweenUserAndPost(ctx, p.db, anthroveUserID, anthrovePostID)
}
func (p *postgresqlConnection) CheckIfUserHasPostAsFavorite(ctx context.Context, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) (bool, error) {
func (p *postgresqlConnection) CheckReferenceBetweenUserAndPost(ctx context.Context, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) (bool, error) {
return postgres.CheckReferenceBetweenUserAndPost(ctx, p.db, anthroveUserID, anthrovePostID)
}
@ -116,23 +116,23 @@ func (p *postgresqlConnection) GetUserFavoritesCount(ctx context.Context, anthro
return postgres.GetUserFavoritesCount(ctx, p.db, anthroveUserID)
}
func (p *postgresqlConnection) GetAllUserSources(ctx context.Context, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) {
func (p *postgresqlConnection) GetUserSourceLinks(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) (*models.UserSource, error) {
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) GetAllUsers(ctx context.Context) ([]models.User, error) {
return postgres.GetAllUsers(ctx, p.db)
func (p *postgresqlConnection) GetAllAnthroveUserIDs(ctx context.Context) ([]models.AnthroveUserID, error) {
return postgres.GetAllAnthroveUserIDs(ctx, p.db)
}
func (p *postgresqlConnection) GetAllUserFavoritesWithPagination(ctx context.Context, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) {
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) GetAllTagsFromUser(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) {
func (p *postgresqlConnection) GetUserTagWitRelationToFavedPosts(ctx context.Context, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) {
return postgres.GetUserTagWitRelationToFavedPosts(ctx, p.db, anthroveUserID)
}
@ -193,21 +193,6 @@ 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"}

View File

@ -420,8 +420,8 @@ func Test_postgresqlConnection_CreateTagAndReferenceToPost(t *testing.T) {
db: gormDB,
debug: true,
}
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)
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)
}
})
}
@ -521,8 +521,8 @@ func Test_postgresqlConnection_CreateReferenceBetweenPostAndSource(t *testing.T)
db: gormDB,
debug: true,
}
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)
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)
}
})
}
@ -713,13 +713,13 @@ func Test_postgresqlConnection_CheckReferenceBetweenUserAndPost(t *testing.T) {
db: gormDB,
debug: true,
}
got, err := p.CheckIfUserHasPostAsFavorite(tt.args.ctx, tt.args.anthroveUserID, tt.args.anthrovePostID)
got, err := p.CheckReferenceBetweenUserAndPost(tt.args.ctx, tt.args.anthroveUserID, tt.args.anthrovePostID)
if (err != nil) != tt.wantErr {
t.Errorf("CheckIfUserHasPostAsFavorite() error = %v, wantErr %v", err, tt.wantErr)
t.Errorf("CheckReferenceBetweenUserAndPost() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("CheckIfUserHasPostAsFavorite() got = %v, want %v", got, tt.want)
t.Errorf("CheckReferenceBetweenUserAndPost() got = %v, want %v", got, tt.want)
}
})
}
@ -1206,13 +1206,13 @@ func Test_postgresqlConnection_GetUserSourceLinks(t *testing.T) {
db: gormDB,
debug: true,
}
got, err := p.GetAllUserSources(tt.args.ctx, tt.args.anthroveUserID)
got, err := p.GetUserSourceLinks(tt.args.ctx, tt.args.anthroveUserID)
if (err != nil) != tt.wantErr {
t.Errorf("GetAllUserSources() 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("GetAllUserSources() got = %v, want %v", got, tt.want)
t.Errorf("GetUserSourceLinks() got = %v, want %v", got, tt.want)
}
})
}
@ -1234,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 := &models.UserSource{
UserID: string(validUserID),
expectedResult["e621"] = models.UserSource{
UserID: "e1",
AccountUsername: "euser",
Source: models.Source{
BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: source.ID},
DisplayName: source.DisplayName,
Domain: source.Domain,
Icon: source.Icon,
@ -1259,7 +1259,7 @@ func Test_postgresqlConnection_GetUserSourceBySourceID(t *testing.T) {
t.Fatal(err)
}
err = postgres.CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, expectedResult.UserID, expectedResult.AccountUsername)
err = postgres.CreateUserWithRelationToSource(ctx, gormDB, validUserID, validSourceID, expectedResult["e621"].UserID, expectedResult["e621"].AccountUsername)
if err != nil {
t.Fatal(err)
}
@ -1270,11 +1270,10 @@ func Test_postgresqlConnection_GetUserSourceBySourceID(t *testing.T) {
anthroveUserID models.AnthroveUserID
sourceID models.AnthroveSourceID
}
tests := []struct {
name string
args args
want *models.UserSource
want map[string]models.UserSource
wantErr bool
}{
{
@ -1349,14 +1348,14 @@ func Test_postgresqlConnection_GetUserSourceBySourceID(t *testing.T) {
t.Errorf("GetUserSourceBySourceID() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !checkUserSource(got, tt.want) {
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("GetUserSourceBySourceID() got = %v, want %v", got, tt.want)
}
})
}
}
func Test_postgresqlConnection_GetAllUsers(t *testing.T) {
func Test_postgresqlConnection_GetAllAnthroveUserIDs(t *testing.T) {
// Setup trow away container
ctx := context.Background()
container, gormDB, err := test.StartPostgresContainer(ctx)
@ -1370,20 +1369,10 @@ func Test_postgresqlConnection_GetAllUsers(t *testing.T) {
validUserID02 := models.AnthroveUserID(fmt.Sprintf("%025s", "User2"))
validUserID03 := models.AnthroveUserID(fmt.Sprintf("%025s", "User3"))
users := []models.User{
{
BaseModel: models.BaseModel[models.AnthroveUserID]{ID: validUserID01},
},
{
BaseModel: models.BaseModel[models.AnthroveUserID]{ID: validUserID02},
},
{
BaseModel: models.BaseModel[models.AnthroveUserID]{ID: validUserID03},
},
}
users := []models.AnthroveUserID{validUserID01, validUserID02, validUserID03}
for _, user := range users {
err = postgres.CreateUser(ctx, gormDB, user.ID)
err = postgres.CreateUser(ctx, gormDB, user)
if err != nil {
t.Fatal(err)
}
@ -1396,7 +1385,7 @@ func Test_postgresqlConnection_GetAllUsers(t *testing.T) {
tests := []struct {
name string
args args
want []models.User
want []models.AnthroveUserID
wantErr bool
}{
{
@ -1413,13 +1402,13 @@ func Test_postgresqlConnection_GetAllUsers(t *testing.T) {
db: gormDB,
debug: true,
}
got, err := p.GetAllUsers(tt.args.ctx)
got, err := p.GetAllAnthroveUserIDs(tt.args.ctx)
if (err != nil) != tt.wantErr {
t.Errorf("GetAllUsers() error = %v, wantErr %v", err, tt.wantErr)
t.Errorf("GetAllAnthroveUserIDs() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !checkUser(got, tt.want) {
t.Errorf("GetAllUsers() got = %v, want %v", got, tt.want)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("GetAllAnthroveUserIDs() got = %v, want %v", got, tt.want)
}
})
}
@ -1550,13 +1539,13 @@ func Test_postgresqlConnection_GetUserFavoriteWithPagination(t *testing.T) {
db: gormDB,
debug: true,
}
got, err := p.GetAllUserFavoritesWithPagination(tt.args.ctx, tt.args.anthroveUserID, tt.args.skip, tt.args.limit)
got, err := p.GetUserFavoriteWithPagination(tt.args.ctx, tt.args.anthroveUserID, tt.args.skip, tt.args.limit)
if (err != nil) != tt.wantErr {
t.Errorf("GetAllUserFavoritesWithPagination() 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("GetAllUserFavoritesWithPagination() got = %v, want %v", got, tt.want)
t.Errorf("GetUserFavoriteWithPagination() got = %v, want %v", got, tt.want)
}
})
}
@ -1664,13 +1653,13 @@ func Test_postgresqlConnection_GetUserTagWitRelationToFavedPosts(t *testing.T) {
db: gormDB,
debug: true,
}
got, err := p.GetAllTagsFromUser(tt.args.ctx, tt.args.anthroveUserID)
got, err := p.GetUserTagWitRelationToFavedPosts(tt.args.ctx, tt.args.anthroveUserID)
if (err != nil) != tt.wantErr {
t.Errorf("GetAllTagsFromUser() 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("GetAllTagsFromUser() got = %v, want %v", got, tt.want)
t.Errorf("GetUserTagWitRelationToFavedPosts() got = %v, want %v", got, tt.want)
}
})
}
@ -1985,38 +1974,3 @@ 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
}

View File

@ -1,19 +0,0 @@
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)
}

View File

@ -1,12 +0,0 @@
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)
}

View File

@ -1,17 +0,0 @@
package database
import (
"context"
"git.dragse.it/anthrove/otter-space-sdk/pkg/models"
)
type TagAlias interface {
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
}

View File

@ -1,17 +0,0 @@
package database
import (
"context"
"git.dragse.it/anthrove/otter-space-sdk/pkg/models"
)
type TagGroup interface {
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
}

View File

@ -1,42 +0,0 @@
package database
import (
"context"
"git.dragse.it/anthrove/otter-space-sdk/pkg/models"
)
type User interface {
// 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
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
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)
// 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)
}

View File

@ -1,5 +1,7 @@
package models
import "google.golang.org/genproto/googleapis/type/date"
type AnthroveUserID string
type AnthrovePostID string
type AnthroveSourceID string
@ -8,8 +10,7 @@ type AnthrovePostURL string
type AnthroveTagGroupName string
type AnthroveTagAliasName string
type AnthroveTagID string
type AnthroveScrapeTimeInterval int
type AnthroveUserLastScrapeTime int
type AnthroveScrapeTimeInterval date.Date
type Rating string
type TagType string

View File

@ -26,15 +26,13 @@ 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,
PostReferenceConfig: PostReferenceConfig{
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,
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)

View File

@ -1,18 +1,13 @@
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
LastScrapeTime time.Time
AccountValidate bool
AccountValidationKey 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
}
func (UserSource) TableName() string {

View File

@ -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"
@ -23,7 +21,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) {
@ -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(60*time.Second)),
)
wait.ForLog("database system is ready to accept connections")))
if err != nil {
return nil, nil, err
}
@ -92,12 +88,12 @@ func DatabaseModesFromConnectionString(ctx context.Context, pgContainer *postgre
return nil, err
}
connectionStringUrl, err := url.Parse(connectionString)
url, err := url.Parse(connectionString)
if err != nil {
return nil, err
}
split := strings.Split(connectionStringUrl.Host, ":")
split := strings.Split(url.Host, ":")
host := split[0]
port, err := strconv.Atoi(split[1])
@ -105,10 +101,10 @@ func DatabaseModesFromConnectionString(ctx context.Context, pgContainer *postgre
return nil, err
}
database := strings.TrimPrefix(connectionStringUrl.Path, "/")
database := strings.TrimPrefix(url.Path, "/")
username := connectionStringUrl.User.Username()
password, _ := connectionStringUrl.User.Password()
username := url.User.Username()
password, _ := url.User.Password()
return &models.DatabaseConfig{
Endpoint: host,