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 }