helpers.go 2.5 KB

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