Refactor Functions and so on #7

Closed
opened 2024-08-09 15:35:48 +00:00 by Alphyron · 4 comments
Owner

I found multiple problems with the current architecture of the SDK. I think we should refactor this.
We are sure that we won't change the Database Driver or create some other complex change. That's the reason why we should remove the thinking about having this SDK as modular as possible.
The Problems we have:

  • For all the specific and small query a single component needs, we need to update his SDK or use custom query. We can't use gorm to build our query ourselves
  • Filtering or Pagination is nor really possible with the current Architecture except writing custom queries
  • Naming scheme is not really clear

With the following solution I want to fix the most problem or make them as small as possible so we need to update this SDK only for database changes, dependency updates or bug fixes.

The Interface should implement the following functions. (I wrote some Model changes down we should implement too)
With these functions we only implement basic CRUD without Read multiple because that should be implemented if needed to filter, sorting and pagination can be implemented with gorm scopes.
Please keep in mind, that I removed the Pointer intentionally!

Connect(ctx context.Context, config models.DatabaseConfig) error

// We should remove the Filter that a User can have only one UserSource with one Source! We should also add the BaseModel to this Model
CreateUserSource(ctx context.Context, userSource models.UserSource) (models.UserSource, error)
UpdateUserSource(ctx context.Context, userSource models.UserSource) error
GetUserSourceByID(ctx context.Context, id models.UserSourceID) (models.UserSource, error)
DeleteUserSource(ctx context.Context, id models.UserSourceID) error

// It is important that UserFavorites also gets the BaseModel and SourceID reference
CreateUserFavorite(ctx context.Context, userFav models.UserFavorites) (models.UserFavorites, error)
CreateUserFavoriteInBatch(ctx context.Context, userFav []models.UserFavorites, batchSize int) error
UpdateUserFavorite(ctx context.Context, userFav models.UserFavorites) error
GetUserFavoritesByID(ctx context.Context, id models.UserFavorites) (models.UserFavorites, error)
DeleteUserFavorite(ctx context.Context, id models.UserFavoritesID) error

CreatePost(ctx context.Context, anthrovePost models.Post) (models.Post, error)
CreatePostInBatch(ctx context.Context, anthrovePost []models.Post, batchSize int) error
GetPostByID(ctx context.Context, anthrovePostID models.AnthrovePostID) (models.Post, error)
UpdatePost(ctx context.Context, anthrovePost models.Post) error
DeletePost(ctx context.Context, id models.AnthrovePostID) error

CreateSource(ctx context.Context, anthroveSource models.Source) (models.Source, error)
CreateSourceInBatch(ctx context.Context, anthroveSource []models.Source, batchSize int) error
UpdateSource(ctx context.Context, anthroveSource models.Source) error
GetSourceByID(ctx context.Context, id models.sourceID) (models.Source, error) 
GetSourceByDomain(ctx context.Context, sourceDomain models.AnthroveSourceDomain) (models.Source, error)
DeleteSource(ctx context.Context, id models.sourceID) error

CreateTag(ctx context.Context, tagName models.AnthroveTagName, tagType models.TagType) error
CreateTagInBatchAndUpdate(ctx context.Context, tags []models.Tag, batchSize int) error
DeleteTag(ctx context.Context, tagName models.AnthroveTagName) error

CreateTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName, tagID models.AnthroveTagID) error
CreateTagAliasInBatch(ctx context.Context, tagsAliases []models.TagAlias, batchSize int) error
DeleteTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName) error

CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) error
CreateTagGroupInBatch(ctx context.Context, tagsGroups []models.TagGroup, batchSize int) error
DeleteTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName) error

GetGorm(ctx context.Context) (gorm.DB, error)

Is there any Point I am missing, or I should recheck?

I found multiple problems with the current architecture of the SDK. I think we should refactor this. We are sure that we won't change the Database Driver or create some other complex change. That's the reason why we should remove the thinking about having this SDK as modular as possible. The Problems we have: - For all the specific and small query a single component needs, we need to update his SDK or use custom query. We can't use gorm to build our query ourselves - Filtering or Pagination is nor really possible with the current Architecture except writing custom queries - Naming scheme is not really clear With the following solution I want to fix the most problem or make them as small as possible so we need to update this SDK only for database changes, dependency updates or bug fixes. The Interface should implement the following functions. (I wrote some Model changes down we should implement too) With these functions we only implement basic CRUD without Read multiple because that should be implemented if needed to filter, sorting and pagination can be implemented with gorm scopes. Please keep in mind, that I removed the Pointer intentionally! ```go Connect(ctx context.Context, config models.DatabaseConfig) error // We should remove the Filter that a User can have only one UserSource with one Source! We should also add the BaseModel to this Model CreateUserSource(ctx context.Context, userSource models.UserSource) (models.UserSource, error) UpdateUserSource(ctx context.Context, userSource models.UserSource) error GetUserSourceByID(ctx context.Context, id models.UserSourceID) (models.UserSource, error) DeleteUserSource(ctx context.Context, id models.UserSourceID) error // It is important that UserFavorites also gets the BaseModel and SourceID reference CreateUserFavorite(ctx context.Context, userFav models.UserFavorites) (models.UserFavorites, error) CreateUserFavoriteInBatch(ctx context.Context, userFav []models.UserFavorites, batchSize int) error UpdateUserFavorite(ctx context.Context, userFav models.UserFavorites) error GetUserFavoritesByID(ctx context.Context, id models.UserFavorites) (models.UserFavorites, error) DeleteUserFavorite(ctx context.Context, id models.UserFavoritesID) error CreatePost(ctx context.Context, anthrovePost models.Post) (models.Post, error) CreatePostInBatch(ctx context.Context, anthrovePost []models.Post, batchSize int) error GetPostByID(ctx context.Context, anthrovePostID models.AnthrovePostID) (models.Post, error) UpdatePost(ctx context.Context, anthrovePost models.Post) error DeletePost(ctx context.Context, id models.AnthrovePostID) error CreateSource(ctx context.Context, anthroveSource models.Source) (models.Source, error) CreateSourceInBatch(ctx context.Context, anthroveSource []models.Source, batchSize int) error UpdateSource(ctx context.Context, anthroveSource models.Source) error GetSourceByID(ctx context.Context, id models.sourceID) (models.Source, error) GetSourceByDomain(ctx context.Context, sourceDomain models.AnthroveSourceDomain) (models.Source, error) DeleteSource(ctx context.Context, id models.sourceID) error CreateTag(ctx context.Context, tagName models.AnthroveTagName, tagType models.TagType) error CreateTagInBatchAndUpdate(ctx context.Context, tags []models.Tag, batchSize int) error DeleteTag(ctx context.Context, tagName models.AnthroveTagName) error CreateTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName, tagID models.AnthroveTagID) error CreateTagAliasInBatch(ctx context.Context, tagsAliases []models.TagAlias, batchSize int) error DeleteTagAlias(ctx context.Context, tagAliasName models.AnthroveTagAliasName) error CreateTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName, tagID models.AnthroveTagID) error CreateTagGroupInBatch(ctx context.Context, tagsGroups []models.TagGroup, batchSize int) error DeleteTagGroup(ctx context.Context, tagGroupName models.AnthroveTagGroupName) error GetGorm(ctx context.Context) (gorm.DB, error) ``` Is there any Point I am missing, or I should recheck?
SoXX was assigned by Alphyron 2024-08-09 15:35:48 +00:00
Owner

This looks good, but you also need to write down what the model changes are

This looks good, but you also need to write down what the model changes are
Author
Owner

This looks good, but you also need to write down what the model changes are

Please read again and you find the changes 😄

Also please don't use a struct with all the functions you need for the interface. Its better to have standalone functions for multiple reason, like best practices and testing and so on.

An example for would be:

client.go:


var dbConfig config.DBConfig
var client *gorm.DB

func Connect(_ context.Context) error {
	if err := env.Parse(&dbConfig); err != nil {
		log.Panic(err)
	}

	dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s TimeZone=Europe/Berlin", dbConfig.Host, dbConfig.User, dbConfig.Pass, dbConfig.DB, dbConfig.Port, dbConfig.SSL)
	sqlDB, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})

	if err != nil {
		return err
	}

	client = sqlDB
	return nil
}

func Migrate(ctx context.Context) error {
	if client == nil {
		return errors.New("db is not connected")
	}

	return client.WithContext(ctx).AutoMigrate(&model.Author{}, &model.Folder{}, &model.Playlist{}, &model.Video{}, &model.UserVideo{})
}

author.go:

func CreateAuthor(ctx context.Context, author *model.Author) error {
	if client == nil {
		return errors.New("db is not connected")
	}

	resp := client.WithContext(ctx).Create(author)

	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

func UpdateAuthor(ctx context.Context, author *model.Author) error {
	if client == nil {
		return errors.New("db is not connected")
	}

	resp := client.WithContext(ctx).Model(&model.Author{
		Model: model.Model{
			ID: author.ID,
		},
	}).Select("*").Updates(author)

	if resp.Error != nil {
		return resp.Error
	}

	return nil
}
> This looks good, but you also need to write down what the model changes are Please read again and you find the changes 😄 Also please don't use a struct with all the functions you need for the interface. Its better to have standalone functions for multiple reason, like best practices and testing and so on. An example for would be: `client.go`: ```go var dbConfig config.DBConfig var client *gorm.DB func Connect(_ context.Context) error { if err := env.Parse(&dbConfig); err != nil { log.Panic(err) } dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s TimeZone=Europe/Berlin", dbConfig.Host, dbConfig.User, dbConfig.Pass, dbConfig.DB, dbConfig.Port, dbConfig.SSL) sqlDB, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) if err != nil { return err } client = sqlDB return nil } func Migrate(ctx context.Context) error { if client == nil { return errors.New("db is not connected") } return client.WithContext(ctx).AutoMigrate(&model.Author{}, &model.Folder{}, &model.Playlist{}, &model.Video{}, &model.UserVideo{}) } ``` `author.go`: ```go func CreateAuthor(ctx context.Context, author *model.Author) error { if client == nil { return errors.New("db is not connected") } resp := client.WithContext(ctx).Create(author) if resp.Error != nil { return resp.Error } return nil } func UpdateAuthor(ctx context.Context, author *model.Author) error { if client == nil { return errors.New("db is not connected") } resp := client.WithContext(ctx).Model(&model.Author{ Model: model.Model{ ID: author.ID, }, }).Select("*").Updates(author) if resp.Error != nil { return resp.Error } return nil } ```
Owner

All base functions are added, so far without tests

All base functions are added, so far without tests
Owner

Could you also write down what kind of telemetry you want to have? i want to add Traces, also logs or something else?

Could you also write down what kind of telemetry you want to have? i want to add Traces, also logs or something else?
SoXX closed this issue 2024-08-29 08:45:49 +00:00
Sign in to join this conversation.
No Label
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: Anthrove/otter-space-sdk#7
No description provided.