github.com/fraugster/parquet-go@v0.12.0/floor/interfaces/unmarshaller.go (about) 1 package interfaces 2 3 import ( 4 "errors" 5 "fmt" 6 ) 7 8 var ( 9 // ErrFieldNotPresent indicate the field is not available in the result 10 ErrFieldNotPresent = errors.New("field is not present") 11 ) 12 13 // Unmarshaller is the interface necessary for objects to 14 // be unmarshalled. 15 type Unmarshaller interface { 16 UnmarshalParquet(obj UnmarshalObject) error 17 } 18 19 // UnmarshalObject is the interface an Unmarshaller needs to unmarshal its data 20 // from. 21 type UnmarshalObject interface { 22 GetField(field string) UnmarshalElement 23 24 GetData() map[string]interface{} 25 } 26 27 // UnmarshalElement describes the interface to get the value of an element in an Unmarshaller 28 // implementation. 29 type UnmarshalElement interface { 30 Group() (UnmarshalObject, error) 31 Int32() (int32, error) 32 Int64() (int64, error) 33 Int96() ([12]byte, error) 34 Float32() (float32, error) 35 Float64() (float64, error) 36 Bool() (bool, error) 37 ByteArray() ([]byte, error) 38 List() (UnmarshalList, error) 39 Map() (UnmarshalMap, error) 40 Error() error 41 } 42 43 // UnmarshalList describes the interface to get the values of a list in an Unmarshaller 44 // implementation. 45 type UnmarshalList interface { 46 Next() bool 47 Value() (UnmarshalElement, error) 48 } 49 50 // UnmarshalMap describes the interface to get key-value pairs of a map in an Unmarshaller 51 // implementation. 52 type UnmarshalMap interface { 53 Next() bool 54 Key() (UnmarshalElement, error) 55 Value() (UnmarshalElement, error) 56 } 57 58 type unmarshalErr struct { 59 } 60 61 func (u unmarshalErr) Error() error { 62 return ErrFieldNotPresent 63 } 64 65 func (u unmarshalErr) Group() (UnmarshalObject, error) { 66 return nil, ErrFieldNotPresent 67 } 68 69 func (u unmarshalErr) Int32() (int32, error) { 70 return 0, ErrFieldNotPresent 71 } 72 73 func (u unmarshalErr) Int64() (int64, error) { 74 return 0, ErrFieldNotPresent 75 } 76 77 func (u unmarshalErr) Int96() ([12]byte, error) { 78 return [12]byte{}, ErrFieldNotPresent 79 } 80 81 func (u unmarshalErr) Float32() (float32, error) { 82 return 0, ErrFieldNotPresent 83 } 84 85 func (u unmarshalErr) Float64() (float64, error) { 86 return 0, ErrFieldNotPresent 87 } 88 89 func (u unmarshalErr) Bool() (bool, error) { 90 return false, ErrFieldNotPresent 91 } 92 93 func (u unmarshalErr) ByteArray() ([]byte, error) { 94 return nil, ErrFieldNotPresent 95 } 96 97 func (u unmarshalErr) List() (UnmarshalList, error) { 98 return nil, ErrFieldNotPresent 99 } 100 101 func (u unmarshalErr) Map() (UnmarshalMap, error) { 102 return nil, ErrFieldNotPresent 103 } 104 105 func (o *object) GetField(field string) UnmarshalElement { 106 fieldData, ok := o.data[field] 107 if !ok { 108 return &unmarshalErr{} 109 } 110 111 return &unmarshElem{data: fieldData} 112 } 113 114 type unmarshElem struct { 115 data interface{} 116 } 117 118 func (e *unmarshElem) Error() error { 119 return nil 120 } 121 122 func (e *unmarshElem) Group() (UnmarshalObject, error) { 123 data, ok := e.data.(map[string]interface{}) 124 if !ok { 125 return nil, errors.New("field is not a group") 126 } 127 128 return &object{data: data}, nil 129 } 130 131 func (e *unmarshElem) Int32() (int32, error) { 132 i, ok := e.data.(int32) 133 if !ok { 134 return 0, fmt.Errorf("expected int32, found %T instead", e.data) 135 } 136 return i, nil 137 } 138 139 func (e *unmarshElem) Int64() (int64, error) { 140 i, ok := e.data.(int64) 141 if !ok { 142 return 0, fmt.Errorf("expected int64, found %T instead", e.data) 143 } 144 return i, nil 145 } 146 147 func (e *unmarshElem) Int96() ([12]byte, error) { 148 i, ok := e.data.([12]byte) 149 if !ok { 150 return [12]byte{}, fmt.Errorf("expected [12]byte, found %T instead", e.data) 151 } 152 return i, nil 153 } 154 155 func (e *unmarshElem) Float32() (float32, error) { 156 f, ok := e.data.(float32) 157 if !ok { 158 return 0, fmt.Errorf("expected float32, found %T instead", e.data) 159 } 160 return f, nil 161 } 162 163 func (e *unmarshElem) Float64() (float64, error) { 164 f, ok := e.data.(float64) 165 if !ok { 166 return 0, fmt.Errorf("expected float64, found %T instead", e.data) 167 } 168 return f, nil 169 } 170 171 func (e *unmarshElem) Bool() (bool, error) { 172 f, ok := e.data.(bool) 173 if !ok { 174 return false, fmt.Errorf("expected bool, found %T instead", e.data) 175 } 176 return f, nil 177 } 178 179 func (e *unmarshElem) ByteArray() ([]byte, error) { 180 f, ok := e.data.([]byte) 181 if !ok { 182 return nil, fmt.Errorf("expected []byte, found %T instead", e.data) 183 } 184 return f, nil 185 } 186 187 func (e *unmarshElem) List() (UnmarshalList, error) { 188 data, ok := e.data.(map[string]interface{}) 189 if !ok { 190 return nil, fmt.Errorf("data is not a list, found %T instead", e.data) 191 } 192 193 isAthenaList := false 194 listData, ok := data["list"] 195 if !ok { 196 listData, ok = data["bag"] 197 if !ok { 198 return nil, errors.New("sub-group list or bag not found") 199 } 200 isAthenaList = true 201 } 202 203 elemList, ok := listData.([]map[string]interface{}) 204 if !ok { 205 return nil, fmt.Errorf("expected sub-group list to be []map[string]interface{}, got %T instead", listData) 206 } 207 208 return &unmarshList{list: elemList, idx: -1, isAthenaList: isAthenaList}, nil 209 } 210 211 func (e *unmarshElem) Map() (UnmarshalMap, error) { 212 data, ok := e.data.(map[string]interface{}) 213 if !ok { 214 return nil, fmt.Errorf("data is not a map, found %T instead", e.data) 215 } 216 217 kvData, ok := data["key_value"] 218 if !ok { 219 return nil, errors.New("sub-group key_value not found") 220 } 221 222 kvList, ok := kvData.([]map[string]interface{}) 223 if !ok { 224 return nil, fmt.Errorf("expected sub-group key_value to be []map[string]interface{}, got %T instead", kvData) 225 } 226 227 return &unmarshMap{data: kvList, idx: -1}, nil 228 } 229 230 type unmarshList struct { 231 list []map[string]interface{} 232 idx int 233 isAthenaList bool 234 } 235 236 func (l *unmarshList) Next() bool { 237 l.idx++ 238 return l.idx < len(l.list) 239 } 240 241 func (l *unmarshList) Value() (UnmarshalElement, error) { 242 if l.idx >= len(l.list) { 243 return nil, errors.New("iterator has reached end of list") 244 } 245 246 elemName := "element" 247 if l.isAthenaList { 248 elemName = "array_element" 249 } 250 251 elem, ok := l.list[l.idx][elemName] 252 if !ok { 253 return nil, fmt.Errorf("%s not found in current list element", elemName) 254 } 255 256 return &unmarshElem{data: elem}, nil 257 } 258 259 type unmarshMap struct { 260 data []map[string]interface{} 261 idx int 262 } 263 264 func (m *unmarshMap) Next() bool { 265 m.idx++ 266 return m.idx < len(m.data) 267 } 268 269 func (m *unmarshMap) Key() (UnmarshalElement, error) { 270 if m.idx >= len(m.data) { 271 return nil, errors.New("iterator has reached end of map") 272 } 273 274 elem, ok := m.data[m.idx]["key"] 275 if !ok { 276 return nil, errors.New("key not found in current map element") 277 } 278 279 return &unmarshElem{data: elem}, nil 280 } 281 282 func (m *unmarshMap) Value() (UnmarshalElement, error) { 283 if m.idx >= len(m.data) { 284 return nil, errors.New("iterator has reached end of map") 285 } 286 287 elem, ok := m.data[m.idx]["value"] 288 if !ok { 289 return nil, errors.New("value not found in current map element") 290 } 291 292 return &unmarshElem{data: elem}, nil 293 } 294 295 // NewUnmarshallObject creates a new unmarshaller object 296 func NewUnmarshallObject(data map[string]interface{}) UnmarshalObject { 297 if data == nil { 298 data = make(map[string]interface{}) 299 } 300 return &object{ 301 data: data, 302 } 303 } 304 305 // NewUnmarshallElement creates new unmarshall element object 306 func NewUnmarshallElement(data interface{}) UnmarshalElement { 307 return &unmarshElem{ 308 data: data, 309 } 310 }