SelectQueryResultType은 쿼리 조회 결과로 나온 칼럼 이름을 key값으로 하고 해당 칼럼의 타입에 관계 없이 그 값을 저장하기 위한 빈 인터페이스 타입의 value를 갖는 map 슬라이스이고 조회된 row 개수 만큼 해당 슬라이스에 append 작업을 수행합니다.

pointers라는 빈(empty) 인터페이스 슬라이스를 추가한 이유는 pq 라이브러리의 Scan() 함수는 조회된 칼럼 값을 저장하기 위한 변수의 주소 값을 인자로 받기 때문에 values 라는 빈(empty) 인터페이스 슬라이스(조회된 칼럼 값을 저장할 공간)의 요소 별 주소 값을 저장하기 위한 슬라이스를 추가적으로 생성합니다.


postgres.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package postgres

import (
"database/sql"
"fmt"
"strings"

_ "github.com/lib/pq"
)

type SelectQueryResultType []map[string]interface{}

func (db *DB) SelectQuery(query string) (SelectQueryResultType, error) {
rows, err := db.db.Query(query)
if err != nil {
return nil, err
}

cols, err := rows.Columns()
if err != nil {
fmt.Printf("db columns fail: %s\n", err)
return nil, err
}

var result SelectQueryResultType

for rows.Next() {
values := make([]interface{}, len(cols))
pointers := make([]interface{}, len(cols))

for i := range values {
pointers[i] = &values[i]
}

if err = rows.Scan(pointers...); err != nil {
fmt.Printf("db scan fail: %s\n", err)
return nil, err
}

row := make(map[string]interface{})
for i, val := range values {
row[strings.ToLower(cols[i])] = val
}

result = append(result, row)
}

return result, nil
}

Reference