samedi 20 juin 2020

Refactoring Golang avoiding manual fields updating between similar structs

I'm using GraphQL and go-pg.

I have many entities like these:

type Player struct {
    ID        int
    CreatedAt time.Time `pg:"default:now(),notnull"`
    TeamID    int `pg:",notnull"`
    Team      *Team
    Type      int
    Score     int64 `pg:",notnull"`
  Note      *string
  // and others...
}

type PlayerInput struct {
    TeamID  int
    Type    int
    Score   int64
    Note    *string
  // and others...
}

I have many times functions like these:

func (db *postgres) Update(context context.Context, id int, input types.PlayerInput) (*types.Player, error) {

    var actualPlayer types.Player

    newPlayer := graphqlToDB(&input)

    tx, err := db.Begin()
    //handle err

    err = tx.Model(&actualPlayer).Where("id = ?", id).For("UPDATE").Select()
    // handle err and rollback

    actualPlayer.TeamID = newPlayer.TeamID
    actualPlayer.Type = newPlayer.Type
    actualPlayer.Score = newPlayer.Score
  actualPlayer.Note = newPlayer.Note
  // and others...

    _, err = tx.Model(&actualPlayer).WherePK().Update()
    // handle err and rollback

    err = tx.Commit()
    //handle err

    return &actualPlayer, nil
}

func graphqlToDB(input *types.PlayerInput) *types.Player {

    var output = &types.Player{
        TeamID:   input.TeamID,
        Type:     input.Type,
        Score:    input.Score,
        Note:     input.Note,
    // and others...
    }

    if input.Type == "example" {
        output.Score = 10000000
  }

    return output
}

I have this code for each entity in my project and I would like to limit/avoid redundant code, specially:

  1. transformation from Graphql input type every time

    newPlayer := graphqlToDB(&input)
    
  2. manual updating of these (and other) fields every time

    actualPlayer.TeamID = newPlayer.TeamID
    actualPlayer.Type = newPlayer.Type
    actualPlayer.Score = newPlayer.Score
    actualPlayer.Note = newPlayer.Note
    
  3. opening and closing DB transaction every time

    tx, err := db.Begin()
    

Am I asking for the moon?

Aucun commentaire:

Enregistrer un commentaire