BSON сопоставить со структурой моделей баз данных - PullRequest
0 голосов
/ 17 февраля 2020

Пытаемся выяснить, как правильно это сделать. Прямо сейчас я могу преобразовать карту bson в свои структуры модели базы данных индивидуально. Но сейчас я просто повторяю много одного и того же кода. Так есть ли лучший способ сделать это?

Пример кода:

type Agent struct {
    FirstName      string   `bson:"firstName,omitempty" json:"firstName,omitempty"`
    LastName       string   `bson:"lastName,omitempty" json:"lastName,omitempty"`
    ProfileImage   string   `bson:"profileImage,omitempty" json:"profileImage,omitempty"`
}

func BSONToAgent(bsonMap primitive.M) (agent Agent, err error) {
    bsonBytes, err := bson.Marshal(bsonMap)
    if err != nil {
        return agent, err
    }
    bson.Unmarshal(bsonBytes, &agent)
    return agent, nil
}

func BSONArrayToAgents(bsonMap []primitive.M) (agents []Agent, err error) {
    for _, item := range bsonMap {
        agent, err := BSONToAgent(item)
        if err != nil {
            return agents, err
        }
        agents = append(agents, agent)
    }
    return agents, nil
}



type Form struct {
    UserID        primitive.ObjectID `bson:"userId,omitempty" json:"userId,omitempty"`
    Name          string             `bson:"name,omitempty" json:"name,omitempty"`
    CreatedAt     time.Time          `bson:"createdAt,omitempty" json:"createdAt,omitempty"`
    UpdatedAt     time.Time          `bson:"updatedAt,omitempty" json:"updatedAt,omitempty"`
}

func BSONArrayToForms(bsonMap []primitive.M) (forms []Form, err error) {
    for _, item := range bsonMap {
        form, err := BSONToForm(item)
        if err != nil {
            return forms, err
        }
        forms = append(forms, form)
    }
    return forms, nil
}

func BSONToForm(bsonMap primitive.M) (form Form, err error) {
    bsonBytes, err := bson.Marshal(bsonMap)
    if err != nil {
        return form, err
    }
    bson.Unmarshal(bsonBytes, &form)
    return form, nil
}



Если вы посмотрите на функции BSONToAgent и BSONToForm, то это почти одна и та же функция, только с другим типом, который она возвращает. И то же самое касается BSONArrayToAgents и BSONArrayToForms. Теперь я хочу реализовать эти функции на всех моих моделях баз данных, чтобы упростить преобразование primitive.M (карта bson), которое возвращается при запросе к базе данных.

Есть ли лучший способ сделать это? Может быть, с помощью интерфейса?

1 Ответ

0 голосов
/ 17 февраля 2020

Если вы используете marshal / unmarshal в качестве средства для перевода bson, вы можете сделать:

func BSONToForm(bsonMap primitive.M, out interface{}) (err error) {
    bsonBytes, err := bson.Marshal(bsonMap)
    if err != nil {
        return form, err
    }
    return bson.Unmarshal(bsonBytes, out)
}

var v Form
BSONToForm(bsonMap,&v)

Это не так хорошо работает для массивов, поэтому вы можете сделать что-то вроде этого:

func BSONArrayToForms(bsonMap []primitive.M, newItem func() interface{}, add func(interface{})) (err error) {
    for _, item := range bsonMap {
        n:=newItem()
        err := BSONToForm(item,n)
        if err != nil {
            return forms, err
        }
        add(n)
    }
    return nil
}

forms:=make([]Form,0)
BSONArrayToForms(bsonArr,func() interface{} {return &Form{}},func(in interface{}) {
   forms=append(forms,*(in.(*Form)))
})

Или один забавный вариант c:

func BSONArrayToForms(bsonMap []primitive.M, newItem func() interface{}) (err error) {
    for _, item := range bsonMap {
        n:=newItem()
        err := BSONToForm(item,n)
        if err != nil {
            return forms, err
        }
    }
    return nil
}

forms:=make([]Form,0)
BSONArrayToForms(bsonArr,func() interface{} {
   forms=append(forms,Form{})
   return &forms[len(forms)-1]})

Эта версия должна убедиться, что возвращенный указатель также хранится в массиве.

...