github.com/vedadiyan/sqlparser@v1.0.0/pkg/sqltypes/named_result.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package sqltypes
    18  
    19  import (
    20  	"errors"
    21  
    22  	querypb "github.com/vedadiyan/sqlparser/pkg/query"
    23  )
    24  
    25  var (
    26  	// ErrNoSuchField indicates a search for a value by an unknown field/column name
    27  	ErrNoSuchField = errors.New("no such field in RowNamedValues")
    28  )
    29  
    30  // RowNamedValues contains a row's values as a map based on Field (aka table column) name
    31  type RowNamedValues map[string]Value
    32  
    33  // ToString returns the named field as string
    34  func (r RowNamedValues) ToString(fieldName string) (string, error) {
    35  	if v, ok := r[fieldName]; ok {
    36  		return v.ToString(), nil
    37  	}
    38  	return "", ErrNoSuchField
    39  }
    40  
    41  // AsString returns the named field as string, or default value if nonexistent/error
    42  func (r RowNamedValues) AsString(fieldName string, def string) string {
    43  	if v, err := r.ToString(fieldName); err == nil {
    44  		return v
    45  	}
    46  	return def
    47  }
    48  
    49  // ToInt64 returns the named field as int64
    50  func (r RowNamedValues) ToInt64(fieldName string) (int64, error) {
    51  	if v, ok := r[fieldName]; ok {
    52  		return v.ToInt64()
    53  	}
    54  	return 0, ErrNoSuchField
    55  }
    56  
    57  func (r RowNamedValues) ToInt32(fieldName string) (int32, error) {
    58  	if v, ok := r[fieldName]; ok {
    59  		return v.ToInt32()
    60  	}
    61  	return 0, ErrNoSuchField
    62  }
    63  
    64  // AsInt64 returns the named field as int64, or default value if nonexistent/error
    65  func (r RowNamedValues) AsInt64(fieldName string, def int64) int64 {
    66  	if v, err := r.ToInt64(fieldName); err == nil {
    67  		return v
    68  	}
    69  	return def
    70  }
    71  
    72  func (r RowNamedValues) AsInt32(fieldName string, def int32) int32 {
    73  	if v, err := r.ToInt32(fieldName); err == nil {
    74  		return v
    75  	}
    76  	return def
    77  }
    78  
    79  // ToUint64 returns the named field as uint64
    80  func (r RowNamedValues) ToUint64(fieldName string) (uint64, error) {
    81  	if v, ok := r[fieldName]; ok {
    82  		return v.ToUint64()
    83  	}
    84  	return 0, ErrNoSuchField
    85  }
    86  
    87  // AsUint64 returns the named field as uint64, or default value if nonexistent/error
    88  func (r RowNamedValues) AsUint64(fieldName string, def uint64) uint64 {
    89  	if v, err := r.ToUint64(fieldName); err == nil {
    90  		return v
    91  	}
    92  	return def
    93  }
    94  
    95  // AsFloat64 returns the named field as float64, or default value if nonexistent/error
    96  func (r RowNamedValues) AsFloat64(fieldName string, def float64) float64 {
    97  	if v, err := r.ToFloat64(fieldName); err == nil {
    98  		return v
    99  	}
   100  	return def
   101  }
   102  
   103  // ToFloat64 returns the named field as float64
   104  func (r RowNamedValues) ToFloat64(fieldName string) (float64, error) {
   105  	if v, ok := r[fieldName]; ok {
   106  		return v.ToFloat64()
   107  	}
   108  	return 0, ErrNoSuchField
   109  }
   110  
   111  // ToBool returns the named field as bool
   112  func (r RowNamedValues) ToBool(fieldName string) (bool, error) {
   113  	if v, ok := r[fieldName]; ok {
   114  		return v.ToBool()
   115  	}
   116  	return false, ErrNoSuchField
   117  }
   118  
   119  // AsBool returns the named field as bool, or default value if nonexistent/error
   120  func (r RowNamedValues) AsBool(fieldName string, def bool) bool {
   121  	if v, err := r.ToBool(fieldName); err == nil {
   122  		return v
   123  	}
   124  	return def
   125  }
   126  
   127  // ToBytes returns the named field as a byte array
   128  func (r RowNamedValues) ToBytes(fieldName string) ([]byte, error) {
   129  	if v, ok := r[fieldName]; ok {
   130  		return v.ToBytes()
   131  	}
   132  	return nil, ErrNoSuchField
   133  }
   134  
   135  // AsBytes returns the named field as a byte array, or default value if nonexistent/error
   136  func (r RowNamedValues) AsBytes(fieldName string, def []byte) []byte {
   137  	if v, err := r.ToBytes(fieldName); err == nil {
   138  		return v
   139  	}
   140  	return def
   141  }
   142  
   143  // NamedResult represents a query result with named values as opposed to ordinal values.
   144  type NamedResult struct {
   145  	Fields       []*querypb.Field `json:"fields"`
   146  	RowsAffected uint64           `json:"rows_affected"`
   147  	InsertID     uint64           `json:"insert_id"`
   148  	Rows         []RowNamedValues `json:"rows"`
   149  }
   150  
   151  // ToNamedResult converts a Result struct into a new NamedResult struct
   152  func ToNamedResult(result *Result) (r *NamedResult) {
   153  	if result == nil {
   154  		return r
   155  	}
   156  	r = &NamedResult{
   157  		Fields:       result.Fields,
   158  		RowsAffected: result.RowsAffected,
   159  		InsertID:     result.InsertID,
   160  	}
   161  	columnOrdinals := make(map[int]string)
   162  	for i, field := range result.Fields {
   163  		columnOrdinals[i] = field.Name
   164  	}
   165  	r.Rows = make([]RowNamedValues, len(result.Rows))
   166  	for rowIndex, row := range result.Rows {
   167  		namedRow := make(RowNamedValues)
   168  		for i, value := range row {
   169  			namedRow[columnOrdinals[i]] = value
   170  		}
   171  		r.Rows[rowIndex] = namedRow
   172  	}
   173  	return r
   174  }
   175  
   176  // Row assumes this result has exactly one row, and returns it, or else returns nil.
   177  // It is useful for queries like:
   178  // - select count(*) from ...
   179  // - select @@read_only
   180  // - select UNIX_TIMESTAMP() from dual
   181  func (r *NamedResult) Row() RowNamedValues {
   182  	if len(r.Rows) != 1 {
   183  		return nil
   184  	}
   185  	return r.Rows[0]
   186  }