@@ -53,36 +53,37 @@ func genericVals(colTypes []string) []interface{} {
5353// the rows as JSON
5454func Query (db service.SQLDB ) RequestProcessFunc {
5555 return func (r * http.Request ) (* serializer.Response , error ) {
56- var queryRequest queryRequest
56+ var queryReq queryRequest
5757 body , err := ioutil .ReadAll (r .Body )
5858 if err != nil {
5959 return nil , err
6060 }
6161
62- err = json .Unmarshal (body , & queryRequest )
63- if err != nil || queryRequest .Query == "" {
62+ err = json .Unmarshal (body , & queryReq )
63+ if err != nil || queryReq .Query == "" {
6464 return nil , serializer .NewHTTPError (http .StatusBadRequest ,
6565 `Bad Request. Expected body: { "query": "SQL statement", "limit": 1234 }` )
6666 }
6767
68- query , limitSet := addLimit (queryRequest .Query , queryRequest .Limit )
69-
7068 // go-sql-driver/mysql QueryContext stops waiting for the query results on
7169 // context cancel, but it does not actually cancel the query on the server
7270
7371 c := make (chan error , 1 )
7472
75- var rows * sql.Rows
7673 conn , err := db .Conn (r .Context ())
74+ if err != nil {
75+ return nil , fmt .Errorf ("failed to get a DB connection: %s" , err )
76+ }
7777 defer conn .Close ()
7878
79- connID , err := getConnID (r , conn )
79+ connID , err := getConnID (conn )
8080 if err != nil {
8181 return nil , fmt .Errorf ("failed to get connection id: %s" , err )
8282 }
8383
84+ var resp * serializer.Response
8485 go func () {
85- rows , err = conn . QueryContext (r .Context (), query )
86+ resp , err = queryContext (r .Context (), conn , queryReq )
8687 c <- err
8788 }()
8889
@@ -103,40 +104,53 @@ func Query(db service.SQLDB) RequestProcessFunc {
103104 return nil , dbError (err )
104105 }
105106
106- defer rows .Close ()
107+ return resp , nil
108+ }
109+ }
107110
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 )
112113
113- columnValsPtr := genericVals ( columnTypes )
114+ var rows * sql. Rows
114115
115- tableData := make ([]map [string ]interface {}, 0 )
116+ rows , err := conn .QueryContext (ctx , query )
117+ if err != nil {
118+ return nil , err
119+ }
116120
117- for rows .Next () {
118- if err := rows .Scan (columnValsPtr ... ); err != nil {
119- return nil , err
120- }
121+ defer rows .Close ()
121122
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 )
126131
127- tableData = append (tableData , colData )
132+ for rows .Next () {
133+ if err := rows .Scan (columnValsPtr ... ); err != nil {
134+ return nil , err
128135 }
129136
130- if err := rows .Err (); err != nil {
137+ colData , err := columnsData (columnNames , columnTypes , columnValsPtr )
138+ if err != nil {
131139 return nil , err
132140 }
133141
134- return serializer .NewQueryResponse (
135- tableData , columnNames , columnTypes , limitSet , queryRequest .Limit ), nil
142+ tableData = append (tableData , colData )
136143 }
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
137151}
138152
139- func getConnID (r * http. Request , conn * sql.Conn ) (uint32 , error ) {
153+ func getConnID (conn * sql.Conn ) (uint32 , error ) {
140154 const connIDQuery = "SELECT CONNECTION_ID()"
141155 var connID uint32
142156
0 commit comments