github.com/team-ide/go-dialect@v1.9.20/vitess/sqltypes/proto3.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 "google.golang.org/protobuf/proto" 21 22 "github.com/team-ide/go-dialect/vitess/vterrors" 23 24 querypb "github.com/team-ide/go-dialect/vitess/query" 25 ) 26 27 // This file contains the proto3 conversion functions for the structures 28 // defined here. 29 30 // RowToProto3 converts []Value to proto3. 31 func RowToProto3(row []Value) *querypb.Row { 32 result := &querypb.Row{} 33 _ = RowToProto3Inplace(row, result) 34 return result 35 } 36 37 // RowToProto3Inplace converts []Value to proto3 and stores the conversion in the provided Row 38 func RowToProto3Inplace(row []Value, result *querypb.Row) int { 39 if result.Lengths == nil { 40 result.Lengths = make([]int64, 0, len(row)) 41 } else { 42 result.Lengths = result.Lengths[:0] 43 } 44 total := 0 45 for _, c := range row { 46 if c.IsNull() { 47 result.Lengths = append(result.Lengths, -1) 48 continue 49 } 50 length := c.Len() 51 result.Lengths = append(result.Lengths, int64(length)) 52 total += length 53 } 54 if result.Values == nil { 55 result.Values = make([]byte, 0, total) 56 } else { 57 result.Values = result.Values[:0] 58 } 59 for _, c := range row { 60 if c.IsNull() { 61 continue 62 } 63 result.Values = append(result.Values, c.Raw()...) 64 } 65 return total 66 } 67 68 // RowsToProto3 converts [][]Value to proto3. 69 func RowsToProto3(rows [][]Value) []*querypb.Row { 70 if len(rows) == 0 { 71 return nil 72 } 73 74 result := make([]*querypb.Row, len(rows)) 75 for i, r := range rows { 76 result[i] = RowToProto3(r) 77 } 78 return result 79 } 80 81 // proto3ToRows converts a proto3 rows to [][]Value. The function is private 82 // because it uses the trusted API. 83 func proto3ToRows(fields []*querypb.Field, rows []*querypb.Row) [][]Value { 84 if len(rows) == 0 { 85 // TODO(sougou): This is needed for backward compatibility. 86 // Remove when it's not needed any more. 87 return [][]Value{} 88 } 89 90 result := make([][]Value, len(rows)) 91 for i, r := range rows { 92 result[i] = MakeRowTrusted(fields, r) 93 } 94 return result 95 } 96 97 // ResultToProto3 converts Result to proto3. 98 func ResultToProto3(qr *Result) *querypb.QueryResult { 99 if qr == nil { 100 return nil 101 } 102 return &querypb.QueryResult{ 103 Fields: qr.Fields, 104 RowsAffected: qr.RowsAffected, 105 InsertId: qr.InsertID, 106 Rows: RowsToProto3(qr.Rows), 107 } 108 } 109 110 // Proto3ToResult converts a proto3 Result to an internal data structure. This function 111 // should be used only if the field info is populated in qr. 112 func Proto3ToResult(qr *querypb.QueryResult) *Result { 113 if qr == nil { 114 return nil 115 } 116 return &Result{ 117 Fields: qr.Fields, 118 RowsAffected: qr.RowsAffected, 119 InsertID: qr.InsertId, 120 Rows: proto3ToRows(qr.Fields, qr.Rows), 121 } 122 } 123 124 // CustomProto3ToResult converts a proto3 Result to an internal data structure. This function 125 // takes a separate fields input because not all QueryResults contain the field info. 126 // In particular, only the first packet of streaming queries contain the field info. 127 func CustomProto3ToResult(fields []*querypb.Field, qr *querypb.QueryResult) *Result { 128 if qr == nil { 129 return nil 130 } 131 return &Result{ 132 Fields: qr.Fields, 133 RowsAffected: qr.RowsAffected, 134 InsertID: qr.InsertId, 135 Rows: proto3ToRows(fields, qr.Rows), 136 } 137 } 138 139 // ResultsToProto3 converts []Result to proto3. 140 func ResultsToProto3(qr []Result) []*querypb.QueryResult { 141 if len(qr) == 0 { 142 return nil 143 } 144 result := make([]*querypb.QueryResult, len(qr)) 145 for i, q := range qr { 146 result[i] = ResultToProto3(&q) 147 } 148 return result 149 } 150 151 // Proto3ToResults converts proto3 results to []Result. 152 func Proto3ToResults(qr []*querypb.QueryResult) []Result { 153 if len(qr) == 0 { 154 return nil 155 } 156 result := make([]Result, len(qr)) 157 for i, q := range qr { 158 result[i] = *Proto3ToResult(q) 159 } 160 return result 161 } 162 163 // QueryResponsesToProto3 converts []QueryResponse to proto3. 164 func QueryResponsesToProto3(qr []QueryResponse) []*querypb.ResultWithError { 165 if len(qr) == 0 { 166 return nil 167 } 168 result := make([]*querypb.ResultWithError, len(qr)) 169 for i, q := range qr { 170 result[i] = &querypb.ResultWithError{ 171 Result: ResultToProto3(q.QueryResult), 172 Error: vterrors.ToVTRPC(q.QueryError), 173 } 174 } 175 return result 176 } 177 178 // Proto3ToQueryReponses converts proto3 queryResponse to []QueryResponse. 179 func Proto3ToQueryReponses(qr []*querypb.ResultWithError) []QueryResponse { 180 if len(qr) == 0 { 181 return nil 182 } 183 result := make([]QueryResponse, len(qr)) 184 for i, q := range qr { 185 result[i] = QueryResponse{ 186 QueryResult: Proto3ToResult(q.Result), 187 QueryError: vterrors.FromVTRPC(q.Error), 188 } 189 } 190 return result 191 } 192 193 // Proto3ResultsEqual compares two arrays of proto3 Result. 194 // reflect.DeepEqual shouldn't be used because of the protos. 195 func Proto3ResultsEqual(r1, r2 []*querypb.QueryResult) bool { 196 if len(r1) != len(r2) { 197 return false 198 } 199 for i, r := range r1 { 200 if !proto.Equal(r, r2[i]) { 201 return false 202 } 203 } 204 return true 205 } 206 207 // Proto3QueryResponsesEqual compares two arrays of proto3 QueryResponse. 208 // reflect.DeepEqual shouldn't be used because of the protos. 209 func Proto3QueryResponsesEqual(r1, r2 []*querypb.ResultWithError) bool { 210 if len(r1) != len(r2) { 211 return false 212 } 213 for i, r := range r1 { 214 if !proto.Equal(r, r2[i]) { 215 return false 216 } 217 } 218 return true 219 } 220 221 // Proto3ValuesEqual compares two arrays of proto3 Value. 222 func Proto3ValuesEqual(v1, v2 []*querypb.Value) bool { 223 if len(v1) != len(v2) { 224 return false 225 } 226 for i, v := range v1 { 227 if !proto.Equal(v, v2[i]) { 228 return false 229 } 230 } 231 return true 232 }