Концепция api менеджера баз данных golang, ошибка с утверждением типа

Базовая концепция создания API диспетчера баз данных для получения данных через API. Я использую GORM для получения данных об экземплярах strcuts. Итак, есть структура 300-400, которая представляет таблицы.

type Users struct {
  ID int64
  Name string
}

type Categories struct {
  ID int64
  Category string
}

На следующем шаге я реализую функцию, которая возвращает правильный экземпляр структуры по имени таблицы, что я получаю через параметр конечной точки API.

func GetModel(model string) interface{} {
  switch model {
  case "users":
    return Users{}
  case "categories"
    return Categories{}
  }
  return false
}

После идет структура операций, в которой единственным полем является БД. Есть методы, например GetLast (), где я хочу использовать функцию GORM db.Last (& users).

func (o Operations) GetLast(model string) interface{} {
  modelStruct := GetModel(model)
  .
  .
  .
  return o.DB.Last(&modelStruct)
}

Есть точки, так что это то, чего я не знаю. Текущее решение не работает, потому что в данном случае это интерфейс. {} Мне нужно сделать утверждение типа подробнее в этом вопросе. Утверждение типа выглядит так:

func (o Operations) GetLast(model string) interface{} {
  modelStruct := GetModel(model)
  .
  test := modelStruct.(Users)
  .
  return o.DB.Last(&test)
}

Это решение работает, но в этом случае я потерял модульность. Я пытаюсь использовать reflect.TypeOf(modelStruct), но он также не работает, потому что результат рефлексии. ТипOf - рефлекс. Тип с не является типом голанга.


person PumpkinSeed    schedule 04.02.2017    source источник


Ответы (1)


В основном я решил проблему, получив модель в виде указателя и после того, как верну ее обратно в виде файла json.

Итак, моя модель следующая:

var Models = map[string]interface{}{
    "users": new(Users),
    "categories": new(Categories),
}

И это возврат новой модели по типу таблицы. что я могу использовать для функции gorm First (). Затем json Marshal и вернитесь.

func (o Operation) First(model string, query url.Values) string {
    modelStruct := Models[model]
    db := o.DB
    db.First(modelStruct)
    response, _ := json.Marshal(modelStruct)
    clear(modelStruct)
    return string(response)
}

Перед возвратом я очищаю указатель модели, потому что функция First () хранит обратные вызовы для последних запросов.

func clear(v interface{}) {
    p := reflect.ValueOf(v).Elem()
    p.Set(reflect.Zero(p.Type()))
}
person PumpkinSeed    schedule 10.02.2017