stardb/result.go

287 lines
6.3 KiB
Go
Raw Permalink Normal View History

2026-03-07 19:27:44 +08:00
package stardb
import (
"fmt"
"reflect"
"time"
)
// StarResult represents a single row result
type StarResult struct {
result []interface{}
columns []string
columnIndex map[string]int
columnsType []reflect.Type
}
// Result returns the raw result slice
func (r *StarResult) Result() []interface{} {
return r.result
}
// Columns returns column names
func (r *StarResult) Columns() []string {
return r.columns
}
// ColumnsType returns column types
func (r *StarResult) ColumnsType() []reflect.Type {
return r.columnsType
}
// IsNil checks if a column value is nil
func (r *StarResult) IsNil(name string) bool {
index, ok := r.columnIndex[name]
if !ok {
return true
}
return r.result[index] == nil
}
// MustString returns column value as string
func (r *StarResult) MustString(name string) string {
index, ok := r.columnIndex[name]
if !ok {
return ""
}
return convertToString(r.result[index])
}
// MustInt returns column value as int
func (r *StarResult) MustInt(name string) int {
return int(r.MustInt64(name))
}
// MustInt32 returns column value as int32
func (r *StarResult) MustInt32(name string) int32 {
return int32(r.MustInt64(name))
}
// MustInt64 returns column value as int64
func (r *StarResult) MustInt64(name string) int64 {
index, ok := r.columnIndex[name]
if !ok {
return 0
}
return convertToInt64(r.result[index])
}
// MustUint64 returns column value as uint64
func (r *StarResult) MustUint64(name string) uint64 {
index, ok := r.columnIndex[name]
if !ok {
return 0
}
return convertToUint64(r.result[index])
}
// MustFloat32 returns column value as float32
func (r *StarResult) MustFloat32(name string) float32 {
return float32(r.MustFloat64(name))
}
// MustFloat64 returns column value as float64
func (r *StarResult) MustFloat64(name string) float64 {
index, ok := r.columnIndex[name]
if !ok {
return 0
}
return convertToFloat64(r.result[index])
}
// MustBool returns column value as bool
func (r *StarResult) MustBool(name string) bool {
index, ok := r.columnIndex[name]
if !ok {
return false
}
return convertToBool(r.result[index])
}
// MustBytes returns column value as []byte
func (r *StarResult) MustBytes(name string) []byte {
index, ok := r.columnIndex[name]
if !ok {
return []byte{}
}
if b, ok := r.result[index].([]byte); ok {
return b
}
return []byte(r.MustString(name))
}
// MustDate returns column value as time.Time
func (r *StarResult) MustDate(name, layout string) time.Time {
index, ok := r.columnIndex[name]
if !ok {
return time.Time{}
}
return convertToTime(r.result[index], layout)
}
// Scan scans the result into provided pointers
// Usage: row.Scan(&id, &name, &email)
func (r *StarResult) Scan(dest ...interface{}) error {
if len(dest) != len(r.result) {
return fmt.Errorf("expected %d destination arguments, got %d", len(r.result), len(dest))
}
for i, d := range dest {
if err := convertAssign(d, r.result[i]); err != nil {
return fmt.Errorf("error scanning column %d: %v", i, err)
}
}
return nil
}
// convertAssign assigns src to dest
func convertAssign(dest, src interface{}) error {
switch d := dest.(type) {
case *string:
*d = convertToString(src)
case *int:
*d = int(convertToInt64(src))
case *int32:
*d = int32(convertToInt64(src))
case *int64:
*d = convertToInt64(src)
case *uint64:
*d = convertToUint64(src)
case *float32:
*d = float32(convertToFloat64(src))
case *float64:
*d = convertToFloat64(src)
case *bool:
*d = convertToBool(src)
case *time.Time:
if t, ok := src.(time.Time); ok {
*d = t
}
case *[]byte:
if b, ok := src.([]byte); ok {
*d = b
}
default:
return fmt.Errorf("unsupported Scan type: %T", dest)
}
return nil
}
// StarResultCol represents a single column result
type StarResultCol struct {
result []interface{}
}
// Result returns the raw result slice
func (c *StarResultCol) Result() []interface{} {
return c.result
}
// Len returns the number of values
func (c *StarResultCol) Len() int {
return len(c.result)
}
// IsNil returns slice of nil checks for each row
func (c *StarResultCol) IsNil() []bool {
result := make([]bool, len(c.result))
for i, v := range c.result {
result[i] = (v == nil)
}
return result
}
// MustString returns all values as strings
func (c *StarResultCol) MustString() []string {
result := make([]string, len(c.result))
for i, v := range c.result {
result[i] = convertToString(v)
}
return result
}
// MustInt returns all values as ints
func (c *StarResultCol) MustInt() []int {
result := make([]int, len(c.result))
for i, v := range c.result {
result[i] = int(convertToInt64(v))
}
return result
}
// MustInt32 returns all values as int32
func (c *StarResultCol) MustInt32() []int32 {
result := make([]int32, len(c.result))
for i, v := range c.result {
result[i] = int32(convertToInt64(v))
}
return result
}
// MustInt64 returns all values as int64
func (c *StarResultCol) MustInt64() []int64 {
result := make([]int64, len(c.result))
for i, v := range c.result {
result[i] = convertToInt64(v)
}
return result
}
// MustUint64 returns all values as uint64
func (c *StarResultCol) MustUint64() []uint64 {
result := make([]uint64, len(c.result))
for i, v := range c.result {
result[i] = convertToUint64(v)
}
return result
}
// MustFloat32 returns all values as float32
func (c *StarResultCol) MustFloat32() []float32 {
result := make([]float32, len(c.result))
for i, v := range c.result {
result[i] = float32(convertToFloat64(v))
}
return result
}
// MustFloat64 returns all values as float64
func (c *StarResultCol) MustFloat64() []float64 {
result := make([]float64, len(c.result))
for i, v := range c.result {
result[i] = convertToFloat64(v)
}
return result
}
// MustBool returns all values as bool
func (c *StarResultCol) MustBool() []bool {
result := make([]bool, len(c.result))
for i, v := range c.result {
result[i] = convertToBool(v)
}
return result
}
// MustBytes returns all values as []byte
func (c *StarResultCol) MustBytes() [][]byte {
result := make([][]byte, len(c.result))
for i, v := range c.result {
if b, ok := v.([]byte); ok {
result[i] = b
} else {
result[i] = []byte(convertToString(v))
}
}
return result
}
// MustDate returns all values as time.Time
func (c *StarResultCol) MustDate(layout string) []time.Time {
result := make([]time.Time, len(c.result))
for i, v := range c.result {
result[i] = convertToTime(v, layout)
}
return result
}