helpers.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package gocql
  2. import "reflect"
  3. type rowData struct {
  4. Columns []string
  5. Values []interface{}
  6. }
  7. // New creates a pointer to an empty version of whatever type
  8. // is referenced by the TypeInfo receiver
  9. func (t *TypeInfo) New() interface{} {
  10. return reflect.New(goType(t)).Interface()
  11. }
  12. func goType(t *TypeInfo) reflect.Type {
  13. switch t.Type {
  14. case TypeVarchar, TypeAscii:
  15. return reflect.TypeOf(*new(string))
  16. case TypeBigInt, TypeCounter, TypeTimestamp:
  17. return reflect.TypeOf(*new(int64))
  18. case TypeBlob:
  19. return reflect.TypeOf(*new([]byte))
  20. case TypeBoolean:
  21. return reflect.TypeOf(*new(bool))
  22. case TypeFloat:
  23. return reflect.TypeOf(*new(float32))
  24. case TypeDouble:
  25. return reflect.TypeOf(*new(float64))
  26. case TypeInt:
  27. return reflect.TypeOf(*new(int))
  28. case TypeUUID, TypeTimeUUID:
  29. return reflect.TypeOf(*new(UUID))
  30. case TypeList, TypeSet:
  31. return reflect.SliceOf(goType(t.Elem))
  32. case TypeMap:
  33. return reflect.MapOf(goType(t.Key), goType(t.Elem))
  34. default:
  35. return nil
  36. }
  37. }
  38. func dereference(i interface{}) interface{} {
  39. return reflect.Indirect(reflect.ValueOf(i)).Interface()
  40. }
  41. func (r *rowData) rowMap(m map[string]interface{}) {
  42. for i, column := range r.Columns {
  43. m[column] = dereference(r.Values[i])
  44. }
  45. }
  46. func (iter *Iter) rowData() (rowData, error) {
  47. if iter.err != nil {
  48. return rowData{}, iter.err
  49. }
  50. columns := make([]string, 0)
  51. values := make([]interface{}, 0)
  52. for _, column := range iter.Columns() {
  53. val := column.TypeInfo.New()
  54. columns = append(columns, column.Name)
  55. values = append(values, val)
  56. }
  57. rowData := rowData{
  58. Columns: columns,
  59. Values: values,
  60. }
  61. return rowData, nil
  62. }
  63. // SliceMap is a helper function to make the API easier to use
  64. // returns the data from the query in the form of []map[string]interface{}
  65. func (iter *Iter) SliceMap() ([]map[string]interface{}, error) {
  66. if iter.err != nil {
  67. return nil, iter.err
  68. }
  69. // Not checking for the error because we just did
  70. rowData, _ := iter.rowData()
  71. dataToReturn := make([]map[string]interface{}, 0)
  72. for iter.Scan(rowData.Values...) {
  73. m := make(map[string]interface{})
  74. rowData.rowMap(m)
  75. dataToReturn = append(dataToReturn, m)
  76. }
  77. if iter.err != nil {
  78. return nil, iter.err
  79. }
  80. return dataToReturn, nil
  81. }
  82. // MapScan takes a map[string]interface{} and populates it with a row
  83. // That is returned from cassandra.
  84. func (iter *Iter) MapScan(m map[string]interface{}) bool {
  85. if iter.err != nil {
  86. return false
  87. }
  88. // Not checking for the error because we just did
  89. rowData, _ := iter.rowData()
  90. if iter.Scan(rowData.Values...) {
  91. rowData.rowMap(m)
  92. return true
  93. }
  94. return false
  95. }