Hej, staram się ostatnio napisać własny ORM w golang. Kompletnie zaciąłem się na funkcji Select(), która docelowo miała przyjmować strukturę z danymi na podstawie których będzie wyszukiwać, slice z indeksami pól w tej strukturze (żeby określić pola po których ma szukać) i slice, do którego będzie zapisywany wynik. Nie mam zielonego pojęcia jak mam zrealizować ostatnie. Zmienna record
w kodzie jest praktycznie rzecz biorąc strukturą o takim samym typie jak podany w parametrze. Dla GO to dalej interface {}
i nie chce go dodać przez append do slice'a o tym sammym typie co obj
w parametrze. Czy istnieje jakaś magia, żeby to zrealizować? Strzasznię utknąłem :/. Z góry dziękuję za pomoc :).
func (db *DB) Select(obj interface{}, searchFileds []int) ([]interface{}, error) {
value := reflect.ValueOf(obj).Elem()
objVals := make([]interface{}, 0) //FIXME
pattern := ""
for i, search := range searchFileds {
name, _, _ := tags(obj, search)
v := value.Field(search).Interface()
objVals = append(objVals, v)
pattern += fmt.Sprintf("%s=$%d", name, i+1)
if i != len(searchFileds)-1 {
pattern += ", "
}
}
if pattern == "" {
return nil, &DBQueryError{}
}
query := fmt.Sprintf("SELECT * FROM %s WHERE %s;", tableName(obj), pattern)
print(query)
rows, err := db.controller.Query(query, objVals...)
if err != nil {
return nil, &DBQueryError{}
}
defer rows.Close()
records := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(obj).Elem()), 0, 0)
for rows.Next() {
record := reflect.New(reflect.TypeOf(obj).Elem()).Interface()
fmt.Println()
recordAddrs := sliceStructMap(record)
rows.Scan(recordAddrs...)
records = append(record, records) // TODO: err
// fmt.Println(record)
}
return records, nil
}