From 509abb0f756970e18658a90a0c28da702d1d951d Mon Sep 17 00:00:00 2001 From: SoXX Date: Wed, 3 Jul 2024 22:54:35 +0200 Subject: [PATCH] feat: upload Posts in batch (no tests) --- internal/postgres/post.go | 35 ++- pkg/database/postgres_test.go | 464 +++++++++++++++++----------------- 2 files changed, 268 insertions(+), 231 deletions(-) diff --git a/internal/postgres/post.go b/internal/postgres/post.go index 72a3b1a..aaf2d63 100644 --- a/internal/postgres/post.go +++ b/internal/postgres/post.go @@ -3,7 +3,6 @@ package postgres import ( "context" "errors" - otterError "git.dragse.it/anthrove/otter-space-sdk/v2/pkg/error" "git.dragse.it/anthrove/otter-space-sdk/v2/pkg/models" @@ -37,6 +36,40 @@ func CreatePost(ctx context.Context, db *gorm.DB, anthrovePost *models.Post) err return nil } +// TODO: Make Tests +func CreatePostInBatch(ctx context.Context, db *gorm.DB, anthrovePost []models.Post, batchSize int) error { + if len(anthrovePost) == 0 { + return &otterError.EntityValidationFailed{Reason: "anthrovePost cannot be empty"} + } + + if anthrovePost == nil { + return &otterError.EntityValidationFailed{Reason: "anthrovePost cannot be nil"} + } + + 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 == "" { diff --git a/pkg/database/postgres_test.go b/pkg/database/postgres_test.go index b48f514..0ba7089 100644 --- a/pkg/database/postgres_test.go +++ b/pkg/database/postgres_test.go @@ -2118,6 +2118,121 @@ func Test_postgresqlConnection_CreateTagAlias(t *testing.T) { } } +func Test_postgresqlConnection_CreateTagAliasInBatch(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + tags := []models.Tag{ + { + Name: "JayTheFerret", + Type: models.Artist, + }, + { + Name: "SoXX", + Type: models.Character, + }, + { + Name: "Dragon", + Type: models.Species, + }, + { + Name: "Fennec", + Type: models.Species, + }, + } + err = postgres.CreateTagInBatchAndUpdate(ctx, gormDB, tags, len(tags)) + if err != nil { + t.Fatal(err) + } + + tagAlias := []models.TagAlias{ + { + Name: "test1", + TagID: tags[0].Name, + }, + { + Name: "test2", + TagID: tags[1].Name, + }, + { + Name: "test3", + TagID: tags[2].Name, + }, + { + Name: "test4", + TagID: tags[3].Name, + }, + } + emptyTagAlias := []models.TagAlias{} + + // Test + type args struct { + ctx context.Context + tagAliases []models.TagAlias + batchSize int + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid Tags", + args: args{ + ctx: ctx, + tagAliases: tagAlias, + batchSize: 10, + }, + wantErr: false, + }, + { + name: "Test 2: Empty Tags", + args: args{ + ctx: ctx, + tagAliases: emptyTagAlias, + batchSize: 10, + }, + wantErr: true, + }, + { + name: "Test 3: Nil Tags", + args: args{ + ctx: ctx, + tagAliases: nil, + batchSize: 10, + }, + wantErr: true, + }, + { + name: "Test 4: No batchSize", + args: args{ + ctx: ctx, + tagAliases: tagAlias, + batchSize: 0, + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.CreateTagAliasInBatch(tt.args.ctx, tt.args.tagAliases, tt.args.batchSize); (err != nil) != tt.wantErr { + t.Errorf("CreateTagAliasInBatch() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + func Test_postgresqlConnection_GetAllTagAlias(t *testing.T) { // Setup trow away container ctx := context.Background() @@ -2467,6 +2582,121 @@ func Test_postgresqlConnection_CreateTagGroup(t *testing.T) { } } +func Test_postgresqlConnection_CreateTagGroupInBatch(t *testing.T) { + // Setup trow away container + ctx := context.Background() + container, gormDB, err := test.StartPostgresContainer(ctx) + if err != nil { + t.Fatalf("Could not start PostgreSQL container: %v", err) + } + defer container.Terminate(ctx) + + // Setup Test + tags := []models.Tag{ + { + Name: "JayTheFerret", + Type: models.Artist, + }, + { + Name: "SoXX", + Type: models.Character, + }, + { + Name: "Dragon", + Type: models.Species, + }, + { + Name: "Fennec", + Type: models.Species, + }, + } + err = postgres.CreateTagInBatchAndUpdate(ctx, gormDB, tags, len(tags)) + if err != nil { + t.Fatal(err) + } + + tagGroup := []models.TagGroup{ + { + Name: "test1", + TagID: tags[0].Name, + }, + { + Name: "test2", + TagID: tags[1].Name, + }, + { + Name: "test3", + TagID: tags[2].Name, + }, + { + Name: "test4", + TagID: tags[3].Name, + }, + } + emptyTagGroup := []models.TagGroup{} + + // Test + type args struct { + ctx context.Context + tagGroups []models.TagGroup + batchSize int + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Test 1: Valid Tags", + args: args{ + ctx: ctx, + tagGroups: tagGroup, + batchSize: 10, + }, + wantErr: false, + }, + { + name: "Test 2: Empty Tags", + args: args{ + ctx: ctx, + tagGroups: emptyTagGroup, + batchSize: 10, + }, + wantErr: true, + }, + { + name: "Test 3: Nil Tags", + args: args{ + ctx: ctx, + tagGroups: nil, + batchSize: 10, + }, + wantErr: true, + }, + { + name: "Test 4: No batchSize", + args: args{ + ctx: ctx, + tagGroups: tagGroup, + batchSize: 0, + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &postgresqlConnection{ + db: gormDB, + debug: true, + } + if err := p.CreateTagGroupInBatch(tt.args.ctx, tt.args.tagGroups, tt.args.batchSize); (err != nil) != tt.wantErr { + t.Errorf("CreateTagGroupInBatch() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + func Test_postgresqlConnection_GetAllTagGroup(t *testing.T) { // Setup trow away container ctx := context.Background() @@ -2718,6 +2948,8 @@ func Test_postgresqlConnection_DeleteTagGroup(t *testing.T) { } } +//-------------------------- + func Test_postgresqlConnection_UpdateUserSourceScrapeTimeInterval(t *testing.T) { // Setup trow away container ctx := context.Background() @@ -3074,6 +3306,8 @@ func Test_postgresqlConnection_UpdateUserSourceValidation(t *testing.T) { } } +//-------------------------- + func Test_postgresqlConnection_DeleteTag(t *testing.T) { // Setup trow away container ctx := context.Background() @@ -3343,233 +3577,3 @@ func Test_postgresqlConnection_CreateTagInBatchAndUpdate(t *testing.T) { }) } } - -func Test_postgresqlConnection_CreateTagAliasInBatch(t *testing.T) { - // Setup trow away container - ctx := context.Background() - container, gormDB, err := test.StartPostgresContainer(ctx) - if err != nil { - t.Fatalf("Could not start PostgreSQL container: %v", err) - } - defer container.Terminate(ctx) - - // Setup Test - tags := []models.Tag{ - { - Name: "JayTheFerret", - Type: models.Artist, - }, - { - Name: "SoXX", - Type: models.Character, - }, - { - Name: "Dragon", - Type: models.Species, - }, - { - Name: "Fennec", - Type: models.Species, - }, - } - err = postgres.CreateTagInBatchAndUpdate(ctx, gormDB, tags, len(tags)) - if err != nil { - t.Fatal(err) - } - - tagAlias := []models.TagAlias{ - { - Name: "test1", - TagID: tags[0].Name, - }, - { - Name: "test2", - TagID: tags[1].Name, - }, - { - Name: "test3", - TagID: tags[2].Name, - }, - { - Name: "test4", - TagID: tags[3].Name, - }, - } - emptyTagAlias := []models.TagAlias{} - - // Test - type args struct { - ctx context.Context - tagAliases []models.TagAlias - batchSize int - } - tests := []struct { - name string - args args - wantErr bool - }{ - { - name: "Test 1: Valid Tags", - args: args{ - ctx: ctx, - tagAliases: tagAlias, - batchSize: 10, - }, - wantErr: false, - }, - { - name: "Test 2: Empty Tags", - args: args{ - ctx: ctx, - tagAliases: emptyTagAlias, - batchSize: 10, - }, - wantErr: true, - }, - { - name: "Test 3: Nil Tags", - args: args{ - ctx: ctx, - tagAliases: nil, - batchSize: 10, - }, - wantErr: true, - }, - { - name: "Test 4: No batchSize", - args: args{ - ctx: ctx, - tagAliases: tagAlias, - batchSize: 0, - }, - wantErr: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &postgresqlConnection{ - db: gormDB, - debug: true, - } - if err := p.CreateTagAliasInBatch(tt.args.ctx, tt.args.tagAliases, tt.args.batchSize); (err != nil) != tt.wantErr { - t.Errorf("CreateTagAliasInBatch() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} - -func Test_postgresqlConnection_CreateTagGroupInBatch(t *testing.T) { - // Setup trow away container - ctx := context.Background() - container, gormDB, err := test.StartPostgresContainer(ctx) - if err != nil { - t.Fatalf("Could not start PostgreSQL container: %v", err) - } - defer container.Terminate(ctx) - - // Setup Test - tags := []models.Tag{ - { - Name: "JayTheFerret", - Type: models.Artist, - }, - { - Name: "SoXX", - Type: models.Character, - }, - { - Name: "Dragon", - Type: models.Species, - }, - { - Name: "Fennec", - Type: models.Species, - }, - } - err = postgres.CreateTagInBatchAndUpdate(ctx, gormDB, tags, len(tags)) - if err != nil { - t.Fatal(err) - } - - tagGroup := []models.TagGroup{ - { - Name: "test1", - TagID: tags[0].Name, - }, - { - Name: "test2", - TagID: tags[1].Name, - }, - { - Name: "test3", - TagID: tags[2].Name, - }, - { - Name: "test4", - TagID: tags[3].Name, - }, - } - emptyTagGroup := []models.TagGroup{} - - // Test - type args struct { - ctx context.Context - tagGroups []models.TagGroup - batchSize int - } - tests := []struct { - name string - args args - wantErr bool - }{ - { - name: "Test 1: Valid Tags", - args: args{ - ctx: ctx, - tagGroups: tagGroup, - batchSize: 10, - }, - wantErr: false, - }, - { - name: "Test 2: Empty Tags", - args: args{ - ctx: ctx, - tagGroups: emptyTagGroup, - batchSize: 10, - }, - wantErr: true, - }, - { - name: "Test 3: Nil Tags", - args: args{ - ctx: ctx, - tagGroups: nil, - batchSize: 10, - }, - wantErr: true, - }, - { - name: "Test 4: No batchSize", - args: args{ - ctx: ctx, - tagGroups: tagGroup, - batchSize: 0, - }, - wantErr: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &postgresqlConnection{ - db: gormDB, - debug: true, - } - if err := p.CreateTagGroupInBatch(tt.args.ctx, tt.args.tagGroups, tt.args.batchSize); (err != nil) != tt.wantErr { - t.Errorf("CreateTagGroupInBatch() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -}