Реорганизация Golang без ручного обновления полей между похожими структурами - PullRequest
0 голосов
/ 20 июня 2020

Я использую GraphQL и go -pg .

У меня много таких сущностей:

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...
}

У меня много раз такие функции :

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
}

У меня есть этот код для каждой сущности в моем проекте, и я хотел бы ограничить / избежать избыточного кода, особенно:

  1. преобразование из типа ввода Graphql каждый раз

    newPlayer := graphqlToDB(&input)
    
  2. ручное обновление этих (и других) полей каждый раз

    actualPlayer.TeamID = newPlayer.TeamID
    actualPlayer.Type = newPlayer.Type
    actualPlayer.Score = newPlayer.Score
    actualPlayer.Note = newPlayer.Note
    
  3. открытие и закрытие транзакции БД каждый раз

    tx, err := db.Begin()
    

Я прошу луну?

1 Ответ

1 голос
/ 20 июня 2020

Я не думаю, что в этом коде есть ненормальная избыточность.

  1. преобразование из типа ввода Graphql каждый раз

преобразование Структуры из внешних моделей во внутренние - это общий шаблон, который помогает разделить проблемы. Кроме того, у вас уже есть функция graphqlToDB, которая позволяет повторно использовать 10 строк кода в ее теле. Вероятно, это настолько хорошо, насколько это возможно.

обновление этих (и других) полей каждый раз вручную

В указанном здесь фрагменте кода c actualPlayer имеет тип types.Player и * Функция 1019 * возвращает объект *types.Player.

Таким образом, вы можете просто написать actualPlayer := graphqlToDB(&input), а затем передать указатель, например tx.Model(actualPlayer). Это спасает от переназначения newPlayer на actualPlayer

открытие и закрытие транзакции БД каждый раз

Если вам нужно каждый раз обращаться к БД транзакционно, то вам нужно каждый раз открывать транзакцию (а затем фиксировать / откатывать). В этом нет лишнего. Рефакторинг может просто привести к потере читабельности.

...