2
0

response.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package httpserver
  2. import (
  3. "log"
  4. "net/http"
  5. "github.com/goccy/go-json"
  6. )
  7. // ColumnInfo represents column metadata.
  8. type ColumnInfo struct {
  9. Name string `json:"name"`
  10. Type string `json:"type"`
  11. }
  12. // QueryResponse represents a query response.
  13. type QueryResponse struct {
  14. Columns []ColumnInfo `json:"columns"`
  15. Rows [][]interface{} `json:"rows"`
  16. RowsAffected int64 `json:"rowsAffected"`
  17. LastInsertID int64 `json:"lastInsertId"`
  18. QueryPlan []string `json:"queryPlan,omitempty"`
  19. // Metrics for usage tracking and billing
  20. BytesRead int64 `json:"bytesRead"` // Total bytes in the result set
  21. RowsReturned int `json:"rowsReturned"` // Number of rows returned
  22. ExecutionTimeMicro int64 `json:"executionTimeMicro"` // Execution time in microseconds
  23. }
  24. // ExecuteResult represents a single execution result.
  25. type ExecuteResult struct {
  26. RowsAffected int64 `json:"rowsAffected"`
  27. LastInsertID int64 `json:"lastInsertId"`
  28. }
  29. // ExecuteResponse represents a batch execution response.
  30. type ExecuteResponse struct {
  31. Results []ExecuteResult `json:"results"`
  32. ExecutionTime string `json:"executionTime"`
  33. }
  34. // ErrorResponse represents an error response.
  35. type ErrorResponse struct {
  36. Error ErrorDetail `json:"error"`
  37. }
  38. // ErrorDetail contains error details.
  39. type ErrorDetail struct {
  40. Code string `json:"code"`
  41. Message string `json:"message"`
  42. Details map[string]interface{} `json:"details,omitempty"`
  43. }
  44. // HTTPError represents an HTTP error with custom fields.
  45. type HTTPError struct {
  46. Code string
  47. Message string
  48. Status int
  49. Details map[string]interface{}
  50. }
  51. func (e *HTTPError) Error() string {
  52. return e.Message
  53. }
  54. // writeJSON writes a JSON response.
  55. func writeJSON(w http.ResponseWriter, status int, data interface{}, pretty bool) {
  56. w.Header().Set("Content-Type", "application/json")
  57. w.WriteHeader(status)
  58. encoder := json.NewEncoder(w)
  59. if pretty {
  60. encoder.SetIndent("", " ")
  61. }
  62. encoder.Encode(data)
  63. }
  64. // writeError writes an error response.
  65. func writeError(w http.ResponseWriter, status int, code, message string, details map[string]interface{}) {
  66. resp := ErrorResponse{
  67. Error: ErrorDetail{
  68. Code: code,
  69. Message: message,
  70. Details: details,
  71. },
  72. }
  73. // Log server errors (5xx status codes)
  74. if status >= 500 {
  75. log.Printf("ERROR [%d] %s: %s", status, code, message)
  76. }
  77. writeJSON(w, status, resp, false)
  78. }