forked from kristoiv/gocqltable
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtype.go
107 lines (101 loc) · 2.53 KB
/
type.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
package gocqltable
import (
"errors"
"fmt"
"reflect"
"time"
"github.com/gocql/gocql"
r "github.com/kristoiv/gocqltable/reflect"
)
type Counter int
func stringTypeOf(i interface{}, fi *r.FieldInfo) (string, error) {
if fi != nil {
switch fi.Type {
case "set":
elemVal := reflect.Indirect(reflect.New(reflect.TypeOf(i).Elem())).Interface()
ct := cassaType(elemVal)
if ct == gocql.TypeCustom {
return "", fmt.Errorf("Unsupported type %T", i)
}
return fmt.Sprintf("set<%v>", ct), nil
}
}
_, isByteSlice := i.([]byte)
if !isByteSlice {
// Check if we found a higher kinded type
switch reflect.ValueOf(i).Kind() {
case reflect.Slice:
elemVal := reflect.Indirect(reflect.New(reflect.TypeOf(i).Elem())).Interface()
ct := cassaType(elemVal)
if ct == gocql.TypeCustom {
return "", fmt.Errorf("Unsupported type %T", i)
}
return fmt.Sprintf("list<%v>", ct), nil
case reflect.Map:
keyVal := reflect.Indirect(reflect.New(reflect.TypeOf(i).Key())).Interface()
elemVal := reflect.Indirect(reflect.New(reflect.TypeOf(i).Elem())).Interface()
keyCt := cassaType(keyVal)
elemCt := cassaType(elemVal)
if keyCt == gocql.TypeCustom || elemCt == gocql.TypeCustom {
return "", fmt.Errorf("Unsupported map key or value type %T", i)
}
return fmt.Sprintf("map<%v, %v>", keyCt, elemCt), nil
}
}
ct := cassaType(i)
if ct == gocql.TypeCustom {
return "", fmt.Errorf("Unsupported type %T", i)
}
return cassaTypeToString(ct)
}
func cassaType(i interface{}) gocql.Type {
switch i.(type) {
case int, int32:
return gocql.TypeInt
case int64:
return gocql.TypeBigInt
case string:
return gocql.TypeVarchar
case float32:
return gocql.TypeFloat
case float64:
return gocql.TypeDouble
case bool:
return gocql.TypeBoolean
case time.Time:
return gocql.TypeTimestamp
case gocql.UUID:
return gocql.TypeUUID
case []byte:
return gocql.TypeBlob
case Counter:
return gocql.TypeCounter
}
return gocql.TypeCustom
}
func cassaTypeToString(t gocql.Type) (string, error) {
switch t {
case gocql.TypeInt:
return "int", nil
case gocql.TypeBigInt:
return "bigint", nil
case gocql.TypeVarchar:
return "varchar", nil
case gocql.TypeFloat:
return "float", nil
case gocql.TypeDouble:
return "double", nil
case gocql.TypeBoolean:
return "boolean", nil
case gocql.TypeTimestamp:
return "timestamp", nil
case gocql.TypeUUID:
return "uuid", nil
case gocql.TypeBlob:
return "blob", nil
case gocql.TypeCounter:
return "counter", nil
default:
return "", errors.New("unkown cassandra type")
}
}