| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- package executor
- import (
- "fmt"
- "strings"
- )
- // Result represents the result of executing a SQL statement.
- type Result struct {
- Columns []string // Column names
- ColumnTypes []string // Column types (for type inference)
- Rows [][]interface{} // Row data
- RowCount int // Number of affected/returned rows
- RowsAffected int64 // Number of rows affected (for INSERT/UPDATE/DELETE)
- LastInsertID int64 // Last insert ID (for INSERT with AUTOINCREMENT)
- CommandTag string // Command type (SELECT, INSERT, UPDATE, DELETE, etc.)
- }
- // NewResult creates a new empty result.
- func NewResult(tag string) *Result {
- return &Result{
- CommandTag: tag,
- Rows: make([][]interface{}, 0),
- }
- }
- // AddColumn adds a column to the result.
- func (r *Result) AddColumn(name string) {
- r.Columns = append(r.Columns, name)
- }
- // AddRow adds a row to the result.
- func (r *Result) AddRow(values ...interface{}) {
- r.Rows = append(r.Rows, values)
- r.RowCount = len(r.Rows)
- }
- // SetRowCount sets the row count (for non-SELECT queries).
- func (r *Result) SetRowCount(count int) {
- r.RowCount = count
- r.RowsAffected = int64(count)
- }
- // SetLastInsertID sets the last insert ID.
- func (r *Result) SetLastInsertID(id int64) {
- r.LastInsertID = id
- }
- // AddColumnWithType adds a column with its type to the result.
- func (r *Result) AddColumnWithType(name, colType string) {
- r.Columns = append(r.Columns, name)
- r.ColumnTypes = append(r.ColumnTypes, colType)
- }
- // GetColumnType returns the type for a column index.
- func (r *Result) GetColumnType(idx int) string {
- if idx < len(r.ColumnTypes) {
- return r.ColumnTypes[idx]
- }
- return "ANY"
- }
- // String returns a string representation of the result.
- func (r *Result) String() string {
- var sb strings.Builder
- if len(r.Columns) > 0 {
- // Calculate column widths
- widths := make([]int, len(r.Columns))
- for i, col := range r.Columns {
- widths[i] = len(col)
- }
- for _, row := range r.Rows {
- for i, val := range row {
- if i < len(widths) {
- w := len(fmt.Sprintf("%v", val))
- if w > widths[i] {
- widths[i] = w
- }
- }
- }
- }
- // Print header
- for i, col := range r.Columns {
- if i > 0 {
- sb.WriteString(" | ")
- }
- sb.WriteString(padRight(col, widths[i]))
- }
- sb.WriteString("\n")
- // Print separator
- for i, w := range widths {
- if i > 0 {
- sb.WriteString("-+-")
- }
- sb.WriteString(strings.Repeat("-", w))
- }
- sb.WriteString("\n")
- // Print rows
- for _, row := range r.Rows {
- for i, val := range row {
- if i > 0 {
- sb.WriteString(" | ")
- }
- if i < len(widths) {
- sb.WriteString(padRight(fmt.Sprintf("%v", val), widths[i]))
- }
- }
- sb.WriteString("\n")
- }
- }
- // Print row count
- sb.WriteString(fmt.Sprintf("(%d row", r.RowCount))
- if r.RowCount != 1 {
- sb.WriteString("s")
- }
- sb.WriteString(")\n")
- return sb.String()
- }
- func padRight(s string, width int) string {
- if len(s) >= width {
- return s
- }
- return s + strings.Repeat(" ", width-len(s))
- }
- // ToMaps converts the result to a slice of maps.
- func (r *Result) ToMaps() []map[string]interface{} {
- result := make([]map[string]interface{}, len(r.Rows))
- for i, row := range r.Rows {
- m := make(map[string]interface{})
- for j, col := range r.Columns {
- if j < len(row) {
- m[col] = row[j]
- }
- }
- result[i] = m
- }
- return result
- }
|