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 }