forked from apache/cassandra-gocql-driver
-
Notifications
You must be signed in to change notification settings - Fork 1
/
helpers.go
111 lines (98 loc) · 2.71 KB
/
helpers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Copyright (c) 2012 The gocql Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gocql
import "reflect"
type rowData struct {
Columns []string
Values []interface{}
}
// New creates a pointer to an empty version of whatever type
// is referenced by the TypeInfo receiver
func (t *TypeInfo) New() interface{} {
return reflect.New(goType(t)).Interface()
}
func goType(t *TypeInfo) reflect.Type {
switch t.Type {
case TypeVarchar, TypeAscii:
return reflect.TypeOf(*new(string))
case TypeBigInt, TypeCounter, TypeTimestamp:
return reflect.TypeOf(*new(int64))
case TypeBlob:
return reflect.TypeOf(*new([]byte))
case TypeBoolean:
return reflect.TypeOf(*new(bool))
case TypeFloat:
return reflect.TypeOf(*new(float32))
case TypeDouble:
return reflect.TypeOf(*new(float64))
case TypeInt:
return reflect.TypeOf(*new(int))
case TypeUUID, TypeTimeUUID:
return reflect.TypeOf(*new(UUID))
case TypeList, TypeSet:
return reflect.SliceOf(goType(t.Elem))
case TypeMap:
return reflect.MapOf(goType(t.Key), goType(t.Elem))
default:
return nil
}
}
func dereference(i interface{}) interface{} {
return reflect.Indirect(reflect.ValueOf(i)).Interface()
}
func (r *rowData) rowMap(m map[string]interface{}) {
for i, column := range r.Columns {
m[column] = dereference(r.Values[i])
}
}
func (iter *Iter) rowData() (rowData, error) {
if iter.err != nil {
return rowData{}, iter.err
}
columns := make([]string, 0)
values := make([]interface{}, 0)
for _, column := range iter.Columns() {
val := column.TypeInfo.New()
columns = append(columns, column.Name)
values = append(values, val)
}
rowData := rowData{
Columns: columns,
Values: values,
}
return rowData, nil
}
// SliceMap is a helper function to make the API easier to use
// returns the data from the query in the form of []map[string]interface{}
func (iter *Iter) SliceMap() ([]map[string]interface{}, error) {
if iter.err != nil {
return nil, iter.err
}
// Not checking for the error because we just did
rowData, _ := iter.rowData()
dataToReturn := make([]map[string]interface{}, 0)
for iter.Scan(rowData.Values...) {
m := make(map[string]interface{})
rowData.rowMap(m)
dataToReturn = append(dataToReturn, m)
}
if iter.err != nil {
return nil, iter.err
}
return dataToReturn, nil
}
// MapScan takes a map[string]interface{} and populates it with a row
// That is returned from cassandra.
func (iter *Iter) MapScan(m map[string]interface{}) bool {
if iter.err != nil {
return false
}
// Not checking for the error because we just did
rowData, _ := iter.rowData()
if iter.Scan(rowData.Values...) {
rowData.rowMap(m)
return true
}
return false
}