@@ -53,36 +53,37 @@ func genericVals(colTypes []string) []interface{} {
53
53
// the rows as JSON
54
54
func Query (db service.SQLDB ) RequestProcessFunc {
55
55
return func (r * http.Request ) (* serializer.Response , error ) {
56
- var queryRequest queryRequest
56
+ var queryReq queryRequest
57
57
body , err := ioutil .ReadAll (r .Body )
58
58
if err != nil {
59
59
return nil , err
60
60
}
61
61
62
- err = json .Unmarshal (body , & queryRequest )
63
- if err != nil || queryRequest .Query == "" {
62
+ err = json .Unmarshal (body , & queryReq )
63
+ if err != nil || queryReq .Query == "" {
64
64
return nil , serializer .NewHTTPError (http .StatusBadRequest ,
65
65
`Bad Request. Expected body: { "query": "SQL statement", "limit": 1234 }` )
66
66
}
67
67
68
- query , limitSet := addLimit (queryRequest .Query , queryRequest .Limit )
69
-
70
68
// go-sql-driver/mysql QueryContext stops waiting for the query results on
71
69
// context cancel, but it does not actually cancel the query on the server
72
70
73
71
c := make (chan error , 1 )
74
72
75
- var rows * sql.Rows
76
73
conn , err := db .Conn (r .Context ())
74
+ if err != nil {
75
+ return nil , fmt .Errorf ("failed to get a DB connection: %s" , err )
76
+ }
77
77
defer conn .Close ()
78
78
79
- connID , err := getConnID (r , conn )
79
+ connID , err := getConnID (conn )
80
80
if err != nil {
81
81
return nil , fmt .Errorf ("failed to get connection id: %s" , err )
82
82
}
83
83
84
+ var resp * serializer.Response
84
85
go func () {
85
- rows , err = conn . QueryContext (r .Context (), query )
86
+ resp , err = queryContext (r .Context (), conn , queryReq )
86
87
c <- err
87
88
}()
88
89
@@ -103,40 +104,53 @@ func Query(db service.SQLDB) RequestProcessFunc {
103
104
return nil , dbError (err )
104
105
}
105
106
106
- defer rows .Close ()
107
+ return resp , nil
108
+ }
109
+ }
107
110
108
- columnNames , columnTypes , err := columnsInfo (rows )
109
- if err != nil {
110
- return nil , err
111
- }
111
+ func queryContext (ctx context.Context , conn * sql.Conn , queryReq queryRequest ) (* serializer.Response , error ) {
112
+ query , limitSet := addLimit (queryReq .Query , queryReq .Limit )
112
113
113
- columnValsPtr := genericVals ( columnTypes )
114
+ var rows * sql. Rows
114
115
115
- tableData := make ([]map [string ]interface {}, 0 )
116
+ rows , err := conn .QueryContext (ctx , query )
117
+ if err != nil {
118
+ return nil , err
119
+ }
116
120
117
- for rows .Next () {
118
- if err := rows .Scan (columnValsPtr ... ); err != nil {
119
- return nil , err
120
- }
121
+ defer rows .Close ()
121
122
122
- colData , err := columnsData (columnNames , columnTypes , columnValsPtr )
123
- if err != nil {
124
- return nil , err
125
- }
123
+ columnNames , columnTypes , err := columnsInfo (rows )
124
+ if err != nil {
125
+ return nil , err
126
+ }
127
+
128
+ columnValsPtr := genericVals (columnTypes )
129
+
130
+ tableData := make ([]map [string ]interface {}, 0 )
126
131
127
- tableData = append (tableData , colData )
132
+ for rows .Next () {
133
+ if err := rows .Scan (columnValsPtr ... ); err != nil {
134
+ return nil , err
128
135
}
129
136
130
- if err := rows .Err (); err != nil {
137
+ colData , err := columnsData (columnNames , columnTypes , columnValsPtr )
138
+ if err != nil {
131
139
return nil , err
132
140
}
133
141
134
- return serializer .NewQueryResponse (
135
- tableData , columnNames , columnTypes , limitSet , queryRequest .Limit ), nil
142
+ tableData = append (tableData , colData )
136
143
}
144
+
145
+ if err := rows .Err (); err != nil {
146
+ return nil , err
147
+ }
148
+
149
+ return serializer .NewQueryResponse (
150
+ tableData , columnNames , columnTypes , limitSet , queryReq .Limit ), nil
137
151
}
138
152
139
- func getConnID (r * http. Request , conn * sql.Conn ) (uint32 , error ) {
153
+ func getConnID (conn * sql.Conn ) (uint32 , error ) {
140
154
const connIDQuery = "SELECT CONNECTION_ID()"
141
155
var connID uint32
142
156
0 commit comments