chore(refactor): removed dead code
This commit is contained in:
parent
3f92bdb325
commit
99ea2d37ab
@ -1,42 +0,0 @@
|
|||||||
package postgres
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"errors"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExecuteRawStatement(ctx context.Context, db *gorm.DB, query string, args ...any) error {
|
|
||||||
if query == "" {
|
|
||||||
return errors.New("query can not be empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
if args == nil {
|
|
||||||
return errors.New("arguments can not be nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
result := db.WithContext(ctx).Exec(query, args...)
|
|
||||||
if result.Error != nil {
|
|
||||||
return result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func QueryRawStatement(ctx context.Context, db *gorm.DB, query string, args ...any) (*sql.Rows, error) {
|
|
||||||
if query == "" {
|
|
||||||
return nil, errors.New("query can not be empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
if args == nil {
|
|
||||||
return nil, errors.New("arguments can not be nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
result, err := db.WithContext(ctx).Raw(query, args...).Rows()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
@ -1,125 +0,0 @@
|
|||||||
package postgres
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"git.anthrove.art/Anthrove/otter-space-sdk/v2/test"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestExecuteRawStatement(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
|
|
||||||
query string
|
|
||||||
args []any
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
want *sql.Rows
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "Test 01: Empty Query",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
query: "",
|
|
||||||
args: nil,
|
|
||||||
},
|
|
||||||
want: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Test 02: Nil Query",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
query: "aasd",
|
|
||||||
args: nil,
|
|
||||||
},
|
|
||||||
want: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
err := ExecuteRawStatement(tt.args.ctx, tt.args.db, tt.args.query, tt.args.args...)
|
|
||||||
if (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("ExecuteRawStatement() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestQueryRawStatement(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
|
|
||||||
query string
|
|
||||||
args []any
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
want *sql.Rows
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "Test 01: Empty Query",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
query: "",
|
|
||||||
args: nil,
|
|
||||||
},
|
|
||||||
want: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Test 02: Nil Query",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
query: "aasd",
|
|
||||||
args: nil,
|
|
||||||
},
|
|
||||||
want: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
got, err := QueryRawStatement(tt.args.ctx, tt.args.db, tt.args.query, tt.args.args...)
|
|
||||||
if (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("QueryRawStatement() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(got, tt.want) {
|
|
||||||
t.Errorf("QueryRawStatement() got = %v, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,131 +0,0 @@
|
|||||||
package postgres
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
otterError "git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/error"
|
|
||||||
|
|
||||||
"git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/models"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func CreatePost(ctx context.Context, db *gorm.DB, anthrovePost *models.Post) error {
|
|
||||||
|
|
||||||
if anthrovePost == 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 &otterError.EntityAlreadyExists{}
|
|
||||||
}
|
|
||||||
return result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RowsAffected == 0 {
|
|
||||||
return &otterError.NoDataWritten{}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"anthrove_post_id": anthrovePost.ID,
|
|
||||||
"anthrove_post_rating": anthrovePost.Rating,
|
|
||||||
}).Trace("database: created anthrove post")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreatePostInBatch(ctx context.Context, db *gorm.DB, anthrovePost []models.Post, batchSize int) error {
|
|
||||||
if anthrovePost == nil {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "anthrovePost cannot be nil"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(anthrovePost) == 0 {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "anthrovePost cannot be empty"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if batchSize == 0 {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "batch size cannot be zero"}
|
|
||||||
}
|
|
||||||
|
|
||||||
result := db.WithContext(ctx).CreateInBatches(anthrovePost, batchSize)
|
|
||||||
if result.Error != nil {
|
|
||||||
if errors.Is(result.Error, gorm.ErrDuplicatedKey) {
|
|
||||||
return &otterError.EntityAlreadyExists{}
|
|
||||||
}
|
|
||||||
return result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RowsAffected == 0 {
|
|
||||||
return &otterError.NoDataWritten{}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"tag_size": len(anthrovePost),
|
|
||||||
"batch_size": batchSize,
|
|
||||||
}).Trace("database: created tag node")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetPostByAnthroveID(ctx context.Context, db *gorm.DB, anthrovePostID models.AnthrovePostID) (*models.Post, error) {
|
|
||||||
|
|
||||||
if anthrovePostID == "" {
|
|
||||||
return nil, &otterError.EntityValidationFailed{Reason: "anthrovePostID is not set"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(anthrovePostID) != 25 {
|
|
||||||
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, &otterError.NoDataFound{}
|
|
||||||
}
|
|
||||||
return nil, result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return &post, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetPostBySourceURL(ctx context.Context, db *gorm.DB, sourceURL string) (*models.Post, error) {
|
|
||||||
|
|
||||||
if sourceURL == "" {
|
|
||||||
return nil, &otterError.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, &otterError.NoDataFound{}
|
|
||||||
}
|
|
||||||
return nil, result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return &post, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetPostBySourceID(ctx context.Context, db *gorm.DB, sourceID models.AnthroveSourceID) (*models.Post, error) {
|
|
||||||
|
|
||||||
if sourceID == "" {
|
|
||||||
return nil, &otterError.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, &otterError.NoDataFound{}
|
|
||||||
}
|
|
||||||
return nil, result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return &post, nil
|
|
||||||
}
|
|
@ -1,469 +0,0 @@
|
|||||||
package postgres
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
_ "github.com/lib/pq"
|
|
||||||
|
|
||||||
"git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/models"
|
|
||||||
"git.anthrove.art/Anthrove/otter-space-sdk/v2/test"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
// Setup Tests
|
|
||||||
|
|
||||||
validPost := &models.Post{
|
|
||||||
BaseModel: models.BaseModel[models.AnthrovePostID]{
|
|
||||||
ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")),
|
|
||||||
},
|
|
||||||
Rating: "safe",
|
|
||||||
}
|
|
||||||
|
|
||||||
invalidPost := &models.Post{
|
|
||||||
Rating: "error",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test
|
|
||||||
type args struct {
|
|
||||||
ctx context.Context
|
|
||||||
db *gorm.DB
|
|
||||||
anthrovePost *models.Post
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "Test 1: Valid AnthrovePostID and Rating",
|
|
||||||
args: args{
|
|
||||||
ctx: context.Background(),
|
|
||||||
db: gormDB,
|
|
||||||
anthrovePost: validPost,
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Test 2: Invalid Rating",
|
|
||||||
args: args{
|
|
||||||
ctx: context.Background(),
|
|
||||||
db: gormDB,
|
|
||||||
anthrovePost: invalidPost,
|
|
||||||
},
|
|
||||||
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) {
|
|
||||||
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 TestGetPostByAnthroveID(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[models.AnthrovePostID]{
|
|
||||||
ID: models.AnthrovePostID(fmt.Sprintf("%025s", "1")),
|
|
||||||
},
|
|
||||||
Rating: "safe",
|
|
||||||
}
|
|
||||||
|
|
||||||
err = CreatePost(ctx, gormDB, post)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Could not create post", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test
|
|
||||||
type args struct {
|
|
||||||
ctx context.Context
|
|
||||||
db *gorm.DB
|
|
||||||
anthrovePostID models.AnthrovePostID
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
want *models.Post
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
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: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Test 3: No anthrovePostID",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
anthrovePostID: "",
|
|
||||||
},
|
|
||||||
want: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
got, err := GetPostByAnthroveID(tt.args.ctx, tt.args.db, tt.args.anthrovePostID)
|
|
||||||
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 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[models.AnthrovePostID]{
|
|
||||||
ID: models.AnthrovePostID(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[models.AnthroveSourceID]{
|
|
||||||
ID: models.AnthroveSourceID(fmt.Sprintf("%025s", "1")),
|
|
||||||
},
|
|
||||||
DisplayName: "e621",
|
|
||||||
Domain: "e621.net",
|
|
||||||
Icon: "https://e621.net/icon.ico",
|
|
||||||
}
|
|
||||||
|
|
||||||
err = CreateSource(ctx, gormDB, &source)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Could not create source", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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: "http://test.org",
|
|
||||||
},
|
|
||||||
want: post,
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Test 2: Invalid sourceURL",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
sourceURL: "1234",
|
|
||||||
},
|
|
||||||
want: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Test 3: No sourceURL",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
sourceURL: "",
|
|
||||||
},
|
|
||||||
want: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
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[models.AnthrovePostID]{
|
|
||||||
ID: models.AnthrovePostID(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[models.AnthroveSourceID]{
|
|
||||||
ID: models.AnthroveSourceID(fmt.Sprintf("%025s", "1")),
|
|
||||||
},
|
|
||||||
DisplayName: "e621",
|
|
||||||
Domain: "e621.net",
|
|
||||||
Icon: "https://e621.net/icon.ico",
|
|
||||||
}
|
|
||||||
|
|
||||||
err = CreateSource(ctx, gormDB, &source)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("Could not create source", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test
|
|
||||||
type args struct {
|
|
||||||
ctx context.Context
|
|
||||||
db *gorm.DB
|
|
||||||
sourceID models.AnthroveSourceID
|
|
||||||
}
|
|
||||||
|
|
||||||
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: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Test 3: No sourceID",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
sourceID: "",
|
|
||||||
},
|
|
||||||
want: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
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 TestCreatePostInBatch(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
|
|
||||||
|
|
||||||
validPosts := []models.Post{
|
|
||||||
{
|
|
||||||
Rating: models.SFW,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Rating: models.NSFW,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Rating: models.Questionable,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
emptyPost := []models.Post{}
|
|
||||||
|
|
||||||
// Test
|
|
||||||
type args struct {
|
|
||||||
ctx context.Context
|
|
||||||
db *gorm.DB
|
|
||||||
anthrovePost []models.Post
|
|
||||||
batchSize int
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "Test 1: Valid Data",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
anthrovePost: validPosts,
|
|
||||||
batchSize: len(validPosts),
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Test 2: Emtpy Data",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
anthrovePost: emptyPost,
|
|
||||||
batchSize: 0,
|
|
||||||
},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Test 3: Nil Data",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
anthrovePost: nil,
|
|
||||||
batchSize: 0,
|
|
||||||
},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Test 4: batchSize 0",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
anthrovePost: validPosts,
|
|
||||||
batchSize: 0,
|
|
||||||
},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if err := CreatePostInBatch(tt.args.ctx, tt.args.db, tt.args.anthrovePost, tt.args.batchSize); (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("CreatePostInBatch() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
@ -1,126 +0,0 @@
|
|||||||
package postgres
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
otterError "git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/error"
|
|
||||||
"git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/models"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
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}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(anthrovePostID) != 25 {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort}
|
|
||||||
}
|
|
||||||
|
|
||||||
if sourceDomain == "" {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "sourceDomain cannot be empty"}
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
return &otterError.NoDataFound{}
|
|
||||||
}
|
|
||||||
if errors.Is(result.Error, gorm.ErrCheckConstraintViolated) {
|
|
||||||
return &otterError.EntityAlreadyExists{}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RowsAffected == 0 {
|
|
||||||
return &otterError.NoDataWritten{}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"anthrove_post_id": anthrovePostID,
|
|
||||||
"anthrove_source_domain": sourceDomain,
|
|
||||||
}).Trace("database: created anthrove post to source link")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) error {
|
|
||||||
|
|
||||||
if anthrovePostID == "" {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(anthrovePostID) != 25 {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort}
|
|
||||||
}
|
|
||||||
|
|
||||||
if anthroveUserID == "" {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"}
|
|
||||||
}
|
|
||||||
|
|
||||||
userFavorite := models.UserFavorite{
|
|
||||||
UserID: string(anthroveUserID),
|
|
||||||
PostID: string(anthrovePostID),
|
|
||||||
}
|
|
||||||
|
|
||||||
result := db.WithContext(ctx).Create(&userFavorite)
|
|
||||||
if result.Error != nil {
|
|
||||||
if errors.Is(result.Error, gorm.ErrDuplicatedKey) {
|
|
||||||
return &otterError.EntityAlreadyExists{}
|
|
||||||
}
|
|
||||||
return result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RowsAffected == 0 {
|
|
||||||
return &otterError.NoDataWritten{}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"anthrove_user_id": anthroveUserID,
|
|
||||||
"anthrove_post_id": anthrovePostID,
|
|
||||||
}).Trace("database: created user to post link")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CheckReferenceBetweenUserAndPost(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, anthrovePostID models.AnthrovePostID) (bool, error) {
|
|
||||||
var count int64
|
|
||||||
|
|
||||||
if anthrovePostID == "" {
|
|
||||||
return false, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(anthrovePostID) != 25 {
|
|
||||||
return false, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort}
|
|
||||||
}
|
|
||||||
|
|
||||||
if anthroveUserID == "" {
|
|
||||||
return false, &otterError.EntityValidationFailed{Reason: "anthroveUserID cannot be empty"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(anthroveUserID) != 25 {
|
|
||||||
return false, &otterError.EntityValidationFailed{Reason: "anthroveUserID needs to be 25 characters long"}
|
|
||||||
}
|
|
||||||
|
|
||||||
result := db.WithContext(ctx).Model(&models.UserFavorite{}).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, &otterError.NoDataFound{}
|
|
||||||
}
|
|
||||||
return false, result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
@ -1,392 +0,0 @@
|
|||||||
package postgres
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/models"
|
|
||||||
"git.anthrove.art/Anthrove/otter-space-sdk/v2/test"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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: validPostID,
|
|
||||||
},
|
|
||||||
Rating: "safe",
|
|
||||||
}
|
|
||||||
|
|
||||||
err = CreatePost(ctx, gormDB, post)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = CreateReferenceBetweenUserAndPost(ctx, gormDB, validUserID, post.ID)
|
|
||||||
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: validUserID,
|
|
||||||
anthrovePostID: post.ID,
|
|
||||||
},
|
|
||||||
want: true,
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
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",
|
|
||||||
},
|
|
||||||
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) {
|
|
||||||
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)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if got != tt.want {
|
|
||||||
t.Errorf("CheckIfUserHasPostAsFavorite() got = %v, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCheckUserToPostLinkWithNoData(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")
|
|
||||||
|
|
||||||
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: validPostID,
|
|
||||||
},
|
|
||||||
Rating: "safe",
|
|
||||||
}
|
|
||||||
|
|
||||||
err = CreatePost(ctx, gormDB, post)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = CreateReferenceBetweenUserAndPost(ctx, gormDB, validUserID, post.ID)
|
|
||||||
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: validUserID,
|
|
||||||
anthrovePostID: post.ID,
|
|
||||||
},
|
|
||||||
want: true,
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
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",
|
|
||||||
},
|
|
||||||
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) {
|
|
||||||
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)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if got != tt.want {
|
|
||||||
t.Errorf("CheckIfUserHasPostAsFavorite() got = %v, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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: validPostID,
|
|
||||||
},
|
|
||||||
Rating: "safe",
|
|
||||||
}
|
|
||||||
|
|
||||||
err = CreatePost(ctx, gormDB, post)
|
|
||||||
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: validUserID,
|
|
||||||
anthrovePostID: post.ID,
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Test 2: Valid AnthroveUserID and invalid AnthrovePostID",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
anthroveUserID: validUserID,
|
|
||||||
anthrovePostID: "123456",
|
|
||||||
},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Test 3: invalid AnthroveUserID and valid AnthrovePostID",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
anthroveUserID: invalidUserID,
|
|
||||||
anthrovePostID: post.ID,
|
|
||||||
},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Test 4: Invalid AnthrovePostID and invalid AnthroveUserID",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
anthroveUserID: invalidUserID,
|
|
||||||
anthrovePostID: "123456",
|
|
||||||
},
|
|
||||||
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) {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
package postgres
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
otterError "git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/error"
|
|
||||||
"git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/models"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CreateSource creates a pgModels.Source
|
|
||||||
func CreateSource(ctx context.Context, db *gorm.DB, anthroveSource *models.Source) error {
|
|
||||||
|
|
||||||
if anthroveSource.Domain == "" {
|
|
||||||
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 &otterError.EntityAlreadyExists{}
|
|
||||||
}
|
|
||||||
return result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RowsAffected == 0 {
|
|
||||||
return &otterError.NoDataWritten{}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
|
|
||||||
if result.Error != nil {
|
|
||||||
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
|
||||||
return nil, &otterError.NoDataFound{}
|
|
||||||
}
|
|
||||||
return nil, result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"tag_amount": result.RowsAffected,
|
|
||||||
}).Trace("database: get all source nodes")
|
|
||||||
|
|
||||||
return sources, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 sourceDomain == "" {
|
|
||||||
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, &otterError.NoDataFound{}
|
|
||||||
}
|
|
||||||
return nil, result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"tag_amount": result.RowsAffected,
|
|
||||||
}).Trace("database: get all source nodes")
|
|
||||||
|
|
||||||
return &sources, nil
|
|
||||||
}
|
|
@ -1,270 +0,0 @@
|
|||||||
package postgres
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/models"
|
|
||||||
"git.anthrove.art/Anthrove/otter-space-sdk/v2/test"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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",
|
|
||||||
}
|
|
||||||
|
|
||||||
invalidSource := &models.Source{
|
|
||||||
BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: validPostID},
|
|
||||||
Domain: "notfound.intern",
|
|
||||||
}
|
|
||||||
|
|
||||||
invalidSourceDomain := &models.Source{
|
|
||||||
BaseModel: models.BaseModel[models.AnthroveSourceID]{ID: validPostID},
|
|
||||||
Domain: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test
|
|
||||||
type args struct {
|
|
||||||
ctx context.Context
|
|
||||||
db *gorm.DB
|
|
||||||
anthroveSource *models.Source
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "Test 1: Valid anthroveSource",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
anthroveSource: validSource,
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Test 2: inValid anthroveSource",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
anthroveSource: invalidSourceDomain,
|
|
||||||
},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Test 3: unique anthroveSource",
|
|
||||||
args: args{
|
|
||||||
ctx: ctx,
|
|
||||||
db: gormDB,
|
|
||||||
anthroveSource: invalidSource,
|
|
||||||
},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 := []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 = CreateSource(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 []models.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 := 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()
|
|
||||||
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 = CreateSource(ctx, gormDB, source)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test
|
|
||||||
type args struct {
|
|
||||||
ctx context.Context
|
|
||||||
db *gorm.DB
|
|
||||||
domain models.AnthroveSourceDomain
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
want *models.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 := GetSourceByDomain(tt.args.ctx, tt.args.db, tt.args.domain)
|
|
||||||
if (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("GetSourceByDomain() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !checkSourceNode(got, tt.want) {
|
|
||||||
t.Errorf("GetSourceByDomain() got = %v, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkSourcesNode(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 checkSourceNode(got *models.Source, want *models.Source) bool {
|
|
||||||
|
|
||||||
if want == nil && got == nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if got.Domain != want.Domain {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
|
|
||||||
}
|
|
@ -1,440 +0,0 @@
|
|||||||
package postgres
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"gorm.io/gorm/clause"
|
|
||||||
|
|
||||||
otterError "git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/error"
|
|
||||||
"git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/models"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func CreateTag(ctx context.Context, db *gorm.DB, tagName models.AnthroveTagName, tagType models.TagType) error {
|
|
||||||
|
|
||||||
if tagName == "" {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "tagName cannot be empty"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if tagType == "" {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "tagType cannot be 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{}
|
|
||||||
}
|
|
||||||
return result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RowsAffected == 0 {
|
|
||||||
return &otterError.NoDataWritten{}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"tag_name": tagName,
|
|
||||||
"tag_type": tagType,
|
|
||||||
}).Trace("database: created tag node")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateTagInBatchAndUpdate(ctx context.Context, db *gorm.DB, tags []models.Tag, batchSize int) error {
|
|
||||||
if len(tags) == 0 {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "tags cannot be empty"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if tags == nil {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "tags cannot be nil"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if batchSize == 0 {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "batch size cannot be zero"}
|
|
||||||
}
|
|
||||||
|
|
||||||
result := db.WithContext(ctx).
|
|
||||||
Clauses(clause.OnConflict{
|
|
||||||
Columns: []clause.Column{{Name: "name"}},
|
|
||||||
DoUpdates: clause.AssignmentColumns([]string{"tag_type"}),
|
|
||||||
}).CreateInBatches(tags, batchSize)
|
|
||||||
if result.Error != nil {
|
|
||||||
if errors.Is(result.Error, gorm.ErrDuplicatedKey) {
|
|
||||||
return &otterError.EntityAlreadyExists{}
|
|
||||||
}
|
|
||||||
return result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RowsAffected == 0 {
|
|
||||||
return &otterError.NoDataWritten{}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"tag_size": len(tags),
|
|
||||||
"batch_size": batchSize,
|
|
||||||
}).Trace("database: created tag node")
|
|
||||||
|
|
||||||
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 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).Model(&models.Tag{}).Where("tag_type = ?", tagType).Scan(&tags)
|
|
||||||
|
|
||||||
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 == "" {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "anthrovePostID cannot be empty"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(anthrovePostID) != 25 {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "anthrovePostID needs to be 25 characters long"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if tag == nil {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "Tag is nil"}
|
|
||||||
}
|
|
||||||
|
|
||||||
pgPost := models.Post{
|
|
||||||
BaseModel: models.BaseModel[models.AnthrovePostID]{
|
|
||||||
ID: anthrovePostID,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
err := db.WithContext(ctx).Model(&pgPost).Association("Tags").Append(tag)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return &otterError.NoDataFound{}
|
|
||||||
}
|
|
||||||
return errors.Join(err, &otterError.NoRelationCreated{})
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"anthrove_post_id": anthrovePostID,
|
|
||||||
"tag_name": tag.Name,
|
|
||||||
"tag_type": tag.Type,
|
|
||||||
}).Trace("database: created tag node")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
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{}
|
|
||||||
}
|
|
||||||
return nil, result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"tag_amount": len(tags),
|
|
||||||
}).Trace("database: got tags")
|
|
||||||
|
|
||||||
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: otterError.AnthroveTagIDEmpty}
|
|
||||||
}
|
|
||||||
|
|
||||||
result := db.WithContext(ctx).Clauses(clause.OnConflict{
|
|
||||||
Columns: []clause.Column{{Name: "name"}},
|
|
||||||
DoNothing: true,
|
|
||||||
}).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 CreateTagAliasInBatch(ctx context.Context, db *gorm.DB, tagAliases []models.TagAlias, batchSize int) error {
|
|
||||||
if len(tagAliases) == 0 {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "tagAliases cannot be empty"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if tagAliases == nil {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "tagAliases cannot be nil"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if batchSize == 0 {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "batch size cannot be zero"}
|
|
||||||
}
|
|
||||||
|
|
||||||
result := db.WithContext(ctx).Clauses(clause.OnConflict{
|
|
||||||
Columns: []clause.Column{{Name: "name"}},
|
|
||||||
DoNothing: true,
|
|
||||||
}).CreateInBatches(tagAliases, batchSize)
|
|
||||||
if result.Error != nil {
|
|
||||||
if errors.Is(result.Error, gorm.ErrDuplicatedKey) {
|
|
||||||
return &otterError.EntityAlreadyExists{}
|
|
||||||
}
|
|
||||||
return result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RowsAffected == 0 {
|
|
||||||
return &otterError.NoDataWritten{}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"tag_size": len(tagAliases),
|
|
||||||
"batch_size": batchSize,
|
|
||||||
}).Trace("database: created tag node")
|
|
||||||
|
|
||||||
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: otterError.AnthroveTagIDEmpty}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
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: otterError.AnthroveTagIDEmpty}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 CreateTagGroupInBatch(ctx context.Context, db *gorm.DB, tagGroups []models.TagGroup, batchSize int) error {
|
|
||||||
if len(tagGroups) == 0 {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "tagAliases cannot be empty"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if tagGroups == nil {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "tagAliases cannot be nil"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if batchSize == 0 {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "batch size cannot be zero"}
|
|
||||||
}
|
|
||||||
|
|
||||||
result := db.WithContext(ctx).CreateInBatches(tagGroups, batchSize)
|
|
||||||
if result.Error != nil {
|
|
||||||
if errors.Is(result.Error, gorm.ErrDuplicatedKey) {
|
|
||||||
return &otterError.EntityAlreadyExists{}
|
|
||||||
}
|
|
||||||
return result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RowsAffected == 0 {
|
|
||||||
return &otterError.NoDataWritten{}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"tag_size": len(tagGroups),
|
|
||||||
"batch_size": batchSize,
|
|
||||||
}).Trace("database: created tag node")
|
|
||||||
|
|
||||||
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: otterError.AnthroveTagIDEmpty}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,398 +0,0 @@
|
|||||||
package postgres
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
otterError "git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/error"
|
|
||||||
"git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/models"
|
|
||||||
gonanoid "github.com/matoous/go-nanoid/v2"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"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 == "" {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(anthroveUserID) != 25 {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort}
|
|
||||||
}
|
|
||||||
|
|
||||||
user := models.User{
|
|
||||||
BaseModel: models.BaseModel[models.AnthroveUserID]{
|
|
||||||
ID: anthroveUserID,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
result := db.WithContext(ctx).FirstOrCreate(&user)
|
|
||||||
if result.Error != nil {
|
|
||||||
|
|
||||||
if errors.Is(result.Error, gorm.ErrDuplicatedKey) {
|
|
||||||
return &otterError.EntityAlreadyExists{}
|
|
||||||
}
|
|
||||||
return result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateUserWithRelationToSource(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, sourceID models.AnthroveSourceID, accountId string, accountUsername string) error {
|
|
||||||
|
|
||||||
if anthroveUserID == "" {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(anthroveUserID) != 25 {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort}
|
|
||||||
}
|
|
||||||
|
|
||||||
if accountId == "" {
|
|
||||||
return &otterError.EntityValidationFailed{Reason: "accountID cannot be empty"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if accountUsername == "" {
|
|
||||||
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
|
|
||||||
FROM "Source" AS source
|
|
||||||
WHERE source.id = $6;`, anthroveUserID, anthroveUserID, accountUsername, accountId, validationCode, sourceID)
|
|
||||||
|
|
||||||
if result.Error != nil {
|
|
||||||
if errors.Is(result.Error, gorm.ErrDuplicatedKey) {
|
|
||||||
return &otterError.EntityAlreadyExists{}
|
|
||||||
}
|
|
||||||
return result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RowsAffected == 0 {
|
|
||||||
return &otterError.NoDataWritten{}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"anthrove_user_id": anthroveUserID,
|
|
||||||
"source_id": sourceID,
|
|
||||||
"account_username": accountUsername,
|
|
||||||
"account_id": accountId,
|
|
||||||
}).Info("database: created user-source relationship")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetUserFavoritesCount(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) (int64, error) {
|
|
||||||
var count int64
|
|
||||||
|
|
||||||
if anthroveUserID == "" {
|
|
||||||
return 0, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(anthroveUserID) != 25 {
|
|
||||||
return 0, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort}
|
|
||||||
}
|
|
||||||
|
|
||||||
result := db.WithContext(ctx).Model(&models.UserFavorite{}).Where("user_id = ?", string(anthroveUserID)).Count(&count)
|
|
||||||
if result.Error != nil {
|
|
||||||
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
|
||||||
return 0, &otterError.NoDataFound{}
|
|
||||||
}
|
|
||||||
return 0, result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"anthrove_user_id": anthroveUserID,
|
|
||||||
"anthrove_user_fav_count": count,
|
|
||||||
}).Trace("database: got user favorite count")
|
|
||||||
|
|
||||||
return count, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetUserSourceLinks(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) (map[string]models.UserSource, error) {
|
|
||||||
var userSources []models.UserSource
|
|
||||||
userSourceMap := make(map[string]models.UserSource)
|
|
||||||
|
|
||||||
if anthroveUserID == "" {
|
|
||||||
return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(anthroveUserID) != 25 {
|
|
||||||
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, &otterError.NoDataFound{}
|
|
||||||
}
|
|
||||||
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,
|
|
||||||
}).Trace("database: got user source link")
|
|
||||||
|
|
||||||
return userSourceMap, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
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}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(anthroveUserID) != 25 {
|
|
||||||
return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort}
|
|
||||||
}
|
|
||||||
|
|
||||||
if sourceID == "" {
|
|
||||||
return nil, &otterError.EntityValidationFailed{Reason: "sourceID cannot be empty"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(sourceID) != 25 {
|
|
||||||
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)
|
|
||||||
if result.Error != nil {
|
|
||||||
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
|
||||||
return nil, &otterError.NoDataFound{}
|
|
||||||
}
|
|
||||||
return nil, result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"anthrove_user_id": anthroveUserID,
|
|
||||||
"source_id": sourceID,
|
|
||||||
}).Trace("database: got specified user source link")
|
|
||||||
|
|
||||||
return &userSource, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetAllUsers(ctx context.Context, db *gorm.DB) ([]models.User, error) {
|
|
||||||
var users []models.User
|
|
||||||
|
|
||||||
result := db.WithContext(ctx).Model(&models.User{}).Find(&users)
|
|
||||||
if result.Error != nil {
|
|
||||||
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
|
||||||
return nil, &otterError.NoDataFound{}
|
|
||||||
}
|
|
||||||
return nil, result.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"anthrove_user_id_count": len(users),
|
|
||||||
}).Trace("database: got all anthrove user IDs")
|
|
||||||
|
|
||||||
return users, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: FIX THE TEST
|
|
||||||
func GetUserFavoriteWithPagination(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID, skip int, limit int) (*models.FavoriteList, error) {
|
|
||||||
var favoritePosts []models.Post
|
|
||||||
|
|
||||||
if anthroveUserID == "" {
|
|
||||||
return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(anthroveUserID) != 25 {
|
|
||||||
return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort}
|
|
||||||
}
|
|
||||||
|
|
||||||
db.WithContext(ctx).Joins("RIGHT JOIN \"UserFavorite\" AS of ON \"Post\".id = of.post_id AND of.user_id = ?", anthroveUserID).Preload("References").Offset(skip).Limit(limit).Find(&favoritePosts)
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"anthrove_user_id": anthroveUserID,
|
|
||||||
"anthrove_user_fav_count": len(favoritePosts),
|
|
||||||
}).Trace("database: got all anthrove user favorites")
|
|
||||||
|
|
||||||
return &models.FavoriteList{Posts: favoritePosts}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetUserTagWitRelationToFavedPosts(ctx context.Context, db *gorm.DB, anthroveUserID models.AnthroveUserID) ([]models.TagsWithFrequency, error) {
|
|
||||||
var queryUserFavorites []selectFrequencyTag
|
|
||||||
|
|
||||||
if anthroveUserID == "" {
|
|
||||||
return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDIsEmpty}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(anthroveUserID) != 25 {
|
|
||||||
return nil, &otterError.EntityValidationFailed{Reason: otterError.AnthroveUserIDToShort}
|
|
||||||
}
|
|
||||||
|
|
||||||
rows, err := db.WithContext(ctx).Raw(
|
|
||||||
`WITH user_posts AS (
|
|
||||||
SELECT post_id FROM "UserFavorite" 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, err
|
|
||||||
}
|
|
||||||
|
|
||||||
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{
|
|
||||||
"anthrove_user_id": anthroveUserID,
|
|
||||||
"tag_amount": len(queryUserFavorites),
|
|
||||||
}).Trace("database: got user tag node with relation to faved posts")
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user