2017-09-30 1 views
-1

DB에서 데이터를 가져 와서이 데이터로 배열을 채우는 추상 함수를 만들고 싶습니다. 배열의 유형은 다를 수 있습니다. 성능 문제로 인해이를 반영하지 않고 작업하고 싶습니다. 그냥 GetDBItems()와 같은 함수를 어디에서나 호출하고 원하는 형식의 DB에서 데이터 배열을 가져 오려고합니다. 하지만 내가 작성한 모든 구현은 당황 스럽다.Golang db에서 데이터를 가져와 배열을 채우는 추상 함수

var events []Event 
GetFullItems("events", "events_list", map[string]interface{}{}, func(size int) []interface{} { 
     events = make([]Event, size, size) 
     proxyEnt := make([]interface{}, size, size) 
     for i, _ := range events { 
      proxyEnt[i] = &events[i] 
     } 
     return proxyEnt 
    }) 

그것은 작동하지만,이 함수를 호출하기 위해 많은 코드에있다, 또한 일부 성능에 문제가있을 수 있습니다 : 여기

type AbstractArrayGetter func(size int) []interface{} 

func GetItems(arrayGetter AbstractArrayGetter) { 
    res := DBResponse{} 
    DB.Get(&res) 
    arr := arrayGetter(len(res.Rows)) 
    for i := 0; i < len(res.Rows); i++ { 
     json.Unmarshal(res.Rows[i].Value, &obj[i]) 
    } 
} 

내가이 함수를 호출 : 여기

이 기능의 구현 이벤트 배열을 인터페이스 배열에 복사하는 것에 대한 설명.

짧은 함수 호출 코드로 반영하지 않고 어떻게 할 수 있습니까? 또는이 경우에 느리게 반영하지 않습니까?

+2

당신은 내가 당신이 프로파일 링을 시도 좋을 것 성능에 문제가있는 경우입니다. 이 코드는 너무 길지 않습니다. 리플렉션을 사용하는 버전을 만들고 얼마나 빨라지는지 확인하십시오. 어떤 종류의 데이터베이스에서 데이터를 가져오고 있는지 확실하지 않습니다 - sql.DB의 스펙을 따르고 있습니까? 컴파일 할 때 데이터 레이아웃을 알고 있습니까? 아니면 동적 데이터를 다루고 있습니까? – mbanzon

+0

나는 아직이 솔루션의 성능을 반영 솔루션과 비교하지는 않았지만 앞으로도 마찬가지입니다. 가장 큰 문제는 올바른 해결책에 관한 것입니다. 올바른 방법이 아닌 것처럼 보입니다. 배열을 복사하여 1 단계의 추상화를 얻는 것입니다. 또한 9 라인을 사용하여 DB에서 데이터를 가져 오는 것은 매우 안 좋은 것 같습니다. couchDB를 사용하고 있습니다. 데이터 레이아웃은 컴파일 타임에 알려져 있습니다. DB에서로드하는 데 필요한 여러 가지 구조체가 많이 있습니다. DB에서 데이터를 가져올 때마다 많은 코드를 작성하고 싶지 않습니다. –

답변

0

성능을 반영하여 성능을 테스트했으며 위의 해결 방법과 비슷합니다. 그래서 누군가가 그것을 필요로한다면, 여기에 반영된 해결책이 있습니다. 이 기능은 DB에서 데이터를 가져 와서 추상적 인 배열을 채워

func GetItems(design string, viewName string, opts map[string]interface{}, arrayType interface{}) (interface{}, error) { 
    res := couchResponse{} 
    opts["limit"] = 100000 
    bytes, err := CouchView(design, viewName, opts) 
    if err != nil { 
     return nil, err 
    } 
    err = json.Unmarshal(bytes, &res) 
    if err != nil { 
     return nil, err 
    } 
    dataType := reflect.TypeOf(arrayType) 
    slice := reflect.MakeSlice(reflect.SliceOf(dataType), len(res.Rows), len(res.Rows)) 
    for i := 0; i < len(res.Rows); i++ { 
     if opts["include_docs"] == true { 
      err = json.Unmarshal(res.Rows[i].Doc, slice.Index(i).Addr().Interface()) 
     } else { 
      err = json.Unmarshal(res.Rows[i].Value, slice.Index(i).Addr().Interface()) 
     } 
     if err != nil { 
      return nil, err 
     } 
    } 
    x := reflect.New(slice.Type()) 
    x.Elem().Set(slice) 
    return x.Interface(), nil 
} 

이 기능을 사용하여 데이터 얻기 :

var e Event 
res, err := GetItems("data", "data_list", map[string]interface{}{}, e) 
관련 문제