helpers.go 2.7 KB

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