github.com/rohankumardubey/aresdb@v0.0.2-0.20190517170215-e54e3ca06b9c/query/common/aql_query_result.go (about) 1 // Copyright (c) 2017-2018 Uber Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package common 16 17 const ( 18 MatrixDataKey = "matrixData" 19 HeadersKey = "headers" 20 ) 21 22 // AQLQueryResult represents final result of one AQL query 23 // 24 // It has 2 possible formats: 25 // Time series result format: 26 // One dimension on each layer: 27 // - there is always an outermost time dimension. it stores the start time of 28 // the bucket/duration (in seconds since Epoch). 29 // - after the time dimension, there could be zero or more layers of additional 30 // dimensions (all values are represented as strings). a special "NULL" string 31 /// is used to represent NULL values. 32 // - there is always a single measure, and the measure type is either float64 33 // or nil (not *float64); 34 // 35 // Non aggregate query result format: 36 // - there will be a "headers" key, value will be a list of column names 37 // - there will be a "matrixData" key, value will be a 2d arary of values (row formated) 38 // 39 // user should use it as only 1 of the 2 formats consistently 40 type AQLQueryResult map[string]interface{} 41 42 // ===== Time series result methods start ===== 43 44 // Set measure value for dimensions 45 func (r AQLQueryResult) Set(dimValues []*string, measureValue *float64) { 46 null := "NULL" 47 var current map[string]interface{} = r 48 for i, dimValue := range dimValues { 49 if dimValue == nil { 50 dimValue = &null 51 } 52 53 if i == len(dimValues)-1 { 54 if measureValue == nil { 55 current[*dimValue] = nil 56 } else { 57 current[*dimValue] = *measureValue 58 } 59 } else { 60 child := current[*dimValue] 61 if child == nil { 62 child = make(map[string]interface{}) 63 current[*dimValue] = child 64 } 65 current = child.(map[string]interface{}) 66 } 67 } 68 } 69 70 // SetHLL sets hll struct to be the leaves of the nested map. 71 func (r AQLQueryResult) SetHLL(dimValues []*string, hll HLL) { 72 null := "NULL" 73 var current map[string]interface{} = r 74 for i, dimValue := range dimValues { 75 if dimValue == nil { 76 dimValue = &null 77 } 78 79 if i == len(dimValues)-1 { 80 current[*dimValue] = hll 81 } else { 82 child := current[*dimValue] 83 if child == nil { 84 child = make(map[string]interface{}) 85 current[*dimValue] = child 86 } 87 current = child.(map[string]interface{}) 88 } 89 } 90 } 91 92 // ===== Time series result methods end ===== 93 94 // ===== Non aggregate query result methods start ===== 95 96 // Append appends one row 97 func (r AQLQueryResult) append(row []interface{}) { 98 if _, ok := r[MatrixDataKey]; !ok { 99 r[MatrixDataKey] = [][]interface{}{} 100 } 101 102 r[MatrixDataKey] = append(r[MatrixDataKey].([][]interface{}), row) 103 } 104 105 func (r AQLQueryResult) Append(dimValues []*string) { 106 values := make([]interface{}, len(dimValues)) 107 for index, v := range dimValues { 108 if v == nil { 109 values[index] = "NULL" 110 } else { 111 values[index] = *v 112 } 113 } 114 r.append(values) 115 } 116 117 // SetHeaders sets headers field for the results 118 func (r AQLQueryResult) SetHeaders(headers []string) { 119 r[HeadersKey] = headers 120 } 121 122 // ===== Non aggregate query result methods end =====