result.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package executor
  2. import (
  3. "fmt"
  4. "strings"
  5. )
  6. // Result represents the result of executing a SQL statement.
  7. type Result struct {
  8. Columns []string // Column names
  9. ColumnTypes []string // Column types (for type inference)
  10. Rows [][]interface{} // Row data
  11. RowCount int // Number of affected/returned rows
  12. RowsAffected int64 // Number of rows affected (for INSERT/UPDATE/DELETE)
  13. LastInsertID int64 // Last insert ID (for INSERT with AUTOINCREMENT)
  14. CommandTag string // Command type (SELECT, INSERT, UPDATE, DELETE, etc.)
  15. }
  16. // NewResult creates a new empty result.
  17. func NewResult(tag string) *Result {
  18. return &Result{
  19. CommandTag: tag,
  20. Rows: make([][]interface{}, 0),
  21. }
  22. }
  23. // AddColumn adds a column to the result.
  24. func (r *Result) AddColumn(name string) {
  25. r.Columns = append(r.Columns, name)
  26. }
  27. // AddRow adds a row to the result.
  28. func (r *Result) AddRow(values ...interface{}) {
  29. for i, v := range values {
  30. if jt, ok := v.(jsonText); ok {
  31. values[i] = string(jt)
  32. }
  33. }
  34. r.Rows = append(r.Rows, values)
  35. r.RowCount = len(r.Rows)
  36. }
  37. // SetRowCount sets the row count (for non-SELECT queries).
  38. func (r *Result) SetRowCount(count int) {
  39. r.RowCount = count
  40. r.RowsAffected = int64(count)
  41. }
  42. // SetLastInsertID sets the last insert ID.
  43. func (r *Result) SetLastInsertID(id int64) {
  44. r.LastInsertID = id
  45. }
  46. // AddColumnWithType adds a column with its type to the result.
  47. func (r *Result) AddColumnWithType(name, colType string) {
  48. r.Columns = append(r.Columns, name)
  49. r.ColumnTypes = append(r.ColumnTypes, colType)
  50. }
  51. // GetColumnType returns the type for a column index.
  52. func (r *Result) GetColumnType(idx int) string {
  53. if idx < len(r.ColumnTypes) {
  54. return r.ColumnTypes[idx]
  55. }
  56. return "ANY"
  57. }
  58. // String returns a string representation of the result.
  59. func (r *Result) String() string {
  60. var sb strings.Builder
  61. if len(r.Columns) > 0 {
  62. // Calculate column widths
  63. widths := make([]int, len(r.Columns))
  64. for i, col := range r.Columns {
  65. widths[i] = len(col)
  66. }
  67. for _, row := range r.Rows {
  68. for i, val := range row {
  69. if i < len(widths) {
  70. w := len(fmt.Sprintf("%v", val))
  71. if w > widths[i] {
  72. widths[i] = w
  73. }
  74. }
  75. }
  76. }
  77. // Print header
  78. for i, col := range r.Columns {
  79. if i > 0 {
  80. sb.WriteString(" | ")
  81. }
  82. sb.WriteString(padRight(col, widths[i]))
  83. }
  84. sb.WriteString("\n")
  85. // Print separator
  86. for i, w := range widths {
  87. if i > 0 {
  88. sb.WriteString("-+-")
  89. }
  90. sb.WriteString(strings.Repeat("-", w))
  91. }
  92. sb.WriteString("\n")
  93. // Print rows
  94. for _, row := range r.Rows {
  95. for i, val := range row {
  96. if i > 0 {
  97. sb.WriteString(" | ")
  98. }
  99. if i < len(widths) {
  100. sb.WriteString(padRight(fmt.Sprintf("%v", val), widths[i]))
  101. }
  102. }
  103. sb.WriteString("\n")
  104. }
  105. }
  106. // Print row count
  107. sb.WriteString(fmt.Sprintf("(%d row", r.RowCount))
  108. if r.RowCount != 1 {
  109. sb.WriteString("s")
  110. }
  111. sb.WriteString(")\n")
  112. return sb.String()
  113. }
  114. func padRight(s string, width int) string {
  115. if len(s) >= width {
  116. return s
  117. }
  118. return s + strings.Repeat(" ", width-len(s))
  119. }
  120. // ToMaps converts the result to a slice of maps.
  121. func (r *Result) ToMaps() []map[string]interface{} {
  122. result := make([]map[string]interface{}, len(r.Rows))
  123. for i, row := range r.Rows {
  124. m := make(map[string]interface{})
  125. for j, col := range r.Columns {
  126. if j < len(row) {
  127. m[col] = row[j]
  128. }
  129. }
  130. result[i] = m
  131. }
  132. return result
  133. }