package database import ( "context" "errors" "git.anthrove.art/Anthrove/otter-space-sdk/v5/internal/utils" otterError "git.anthrove.art/Anthrove/otter-space-sdk/v5/pkg/error" "git.anthrove.art/Anthrove/otter-space-sdk/v5/pkg/models" log "github.com/sirupsen/logrus" "go.opentelemetry.io/otel/attribute" "gorm.io/gorm" ) func CreateUserSource(ctx context.Context, userSource models.UserSource) (models.UserSource, error) { ctx, span, localLogger := utils.SetupTracing(ctx, tracer, "CreateUserSource") defer span.End() utils.HandleEvent(span, localLogger, "Starting user source creation") if client == nil { return models.UserSource{}, utils.HandleError(ctx, span, localLogger, &otterError.Database{Reason: otterError.DatabaseIsNotConnected}) } result := client.WithContext(ctx).Create(&userSource) if result.Error != nil { if errors.Is(result.Error, gorm.ErrDuplicatedKey) { return models.UserSource{}, utils.HandleError(ctx, span, localLogger, &otterError.Database{Reason: otterError.DuplicateKey}) } return models.UserSource{}, utils.HandleError(ctx, span, localLogger, result.Error) } localLogger = localLogger.WithFields(log.Fields{ "user_source_id": userSource.ID, }) span.SetAttributes( attribute.String("user_source_id", string(userSource.SourceID)), ) utils.HandleEvent(span, localLogger, "User source created successfully") return userSource, nil } // UpdateUserSource updates the user source information in the database. // Only a few parameter can be updated: // - AccountID // - ScrapeTimeInterval // - AccountUsername // - LastScrapeTime // - AccountValidate func UpdateUserSource(ctx context.Context, userSource models.UserSource) error { ctx, span, localLogger := utils.SetupTracing(ctx, tracer, "UpdateUserSource") defer span.End() localLogger = localLogger.WithFields(log.Fields{ "user_source_id": userSource.ID, }) span.SetAttributes( attribute.String("user_source_id", string(userSource.ID)), ) utils.HandleEvent(span, localLogger, "Starting user source update") if client == nil { return utils.HandleError(ctx, span, localLogger, &otterError.Database{Reason: otterError.DatabaseIsNotConnected}) } if len(userSource.ID) == 0 { return utils.HandleError(ctx, span, localLogger, &otterError.Database{Reason: otterError.UserSourceIDIsEmpty}) } updatedUserSource := models.UserSource{ BaseModel: models.BaseModel[models.UserSourceID]{ ID: userSource.ID, }, ScrapeTimeInterval: userSource.ScrapeTimeInterval, AccountUsername: userSource.AccountUsername, AccountID: userSource.AccountID, LastScrapeTime: userSource.LastScrapeTime, AccountValidate: userSource.AccountValidate, } result := client.WithContext(ctx).Updates(&updatedUserSource) if result.Error != nil { if errors.Is(result.Error, gorm.ErrDuplicatedKey) { return utils.HandleError(ctx, span, localLogger, &otterError.Database{Reason: otterError.DuplicateKey}) } return utils.HandleError(ctx, span, localLogger, result.Error) } utils.HandleEvent(span, localLogger, "User source updated successfully") return nil } func GetUserSourceByID(ctx context.Context, id models.UserSourceID) (models.UserSource, error) { ctx, span, localLogger := utils.SetupTracing(ctx, tracer, "GetUserSourceByID") defer span.End() localLogger = localLogger.WithFields(log.Fields{ "user_source_id": id, }) span.SetAttributes( attribute.String("user_source_id", string(id)), ) utils.HandleEvent(span, localLogger, "Starting get user source by ID") var user models.UserSource if client == nil { return models.UserSource{}, utils.HandleError(ctx, span, localLogger, &otterError.Database{Reason: otterError.DatabaseIsNotConnected}) } if len(id) == 0 { return models.UserSource{}, utils.HandleError(ctx, span, localLogger, &otterError.EntityValidationFailed{Reason: otterError.UserSourceIDIsEmpty}) } if len(id) != 25 { return models.UserSource{}, utils.HandleError(ctx, span, localLogger, &otterError.EntityValidationFailed{Reason: otterError.UserSourceIsWrongLength}) } result := client.WithContext(ctx).First(&user, "id = ?", id) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { return models.UserSource{}, utils.HandleError(ctx, span, localLogger, otterError.Database{Reason: otterError.NoDataFound}) } return models.UserSource{}, utils.HandleError(ctx, span, localLogger, result.Error) } utils.HandleEvent(span, localLogger, "User source retrieved successfully") return user, nil } func DeleteUserSource(ctx context.Context, id models.UserSourceID) error { ctx, span, localLogger := utils.SetupTracing(ctx, tracer, "DeleteUserSource") defer span.End() localLogger = localLogger.WithFields(log.Fields{ "user_source_id": id, }) span.SetAttributes( attribute.String("user_source_id", string(id)), ) utils.HandleEvent(span, localLogger, "Starting delete user source") var user models.UserSource if client == nil { return utils.HandleError(ctx, span, localLogger, &otterError.Database{Reason: otterError.DatabaseIsNotConnected}) } if len(id) == 0 { return utils.HandleError(ctx, span, localLogger, &otterError.EntityValidationFailed{Reason: otterError.UserSourceIDIsEmpty}) } if len(id) != 25 { return utils.HandleError(ctx, span, localLogger, &otterError.EntityValidationFailed{Reason: otterError.UserSourceIsWrongLength}) } result := client.WithContext(ctx).Delete(&user, id) if result.Error != nil { if errors.Is(result.Error, gorm.ErrRecordNotFound) { return utils.HandleError(ctx, span, localLogger, &otterError.Database{Reason: otterError.NoDataFound}) } return result.Error } utils.HandleEvent(span, localLogger, "User source deleted successfully") return nil }