otter-space-sdk/internal/postgres/tag.go

441 lines
11 KiB
Go

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
}