parser.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. package hbaseutil
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "github.com/tsuna/gohbase/hrpc"
  6. "go-common/library/log"
  7. "reflect"
  8. "strconv"
  9. )
  10. /*
  11. add tag for struct fields:
  12. you can add tag:
  13. family: for hbase family, can be omitted, if omitted, the qualifier would be set at whatever famliy
  14. qualifier: for hbase qualifier
  15. if omitted, the fields must be map[string]int or map[string]string
  16. see parser_test.go for detail
  17. */
  18. type field struct {
  19. parser *Parser
  20. name string
  21. structField reflect.StructField
  22. fieldValue reflect.Value
  23. family string
  24. }
  25. func (f *field) isValid() bool {
  26. return f.fieldValue.IsValid()
  27. }
  28. func (f *field) setValue(c *hrpc.Cell) (err error) {
  29. if c == nil {
  30. return
  31. }
  32. if f.fieldValue.Kind() == reflect.Ptr {
  33. f.fieldValue.Set(reflect.New(f.fieldValue.Type().Elem()))
  34. f.fieldValue = f.fieldValue.Elem()
  35. }
  36. switch f.fieldValue.Kind() {
  37. case reflect.Map:
  38. err = f.setMap(c)
  39. default:
  40. err = setBasicValue(c.Value, f.fieldValue, f.name, f.parser.ParseIntFunc)
  41. }
  42. return
  43. }
  44. func setBasicValue(value []byte, rv reflect.Value, name string, parsefunc ParseIntFunc) (err error) {
  45. if rv.Kind() == reflect.Ptr {
  46. if rv.IsNil() {
  47. rv.Set(reflect.New(rv.Type().Elem()))
  48. }
  49. rv = rv.Elem()
  50. }
  51. switch rv.Kind() {
  52. case reflect.String:
  53. rv.Set(reflect.ValueOf(string(value)))
  54. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  55. var i, e = parsefunc(value, rv, name)
  56. if e != nil {
  57. err = fmt.Errorf("field=%s, fail to convert: %s", name, e)
  58. return
  59. }
  60. if rv.OverflowInt(int64(i)) {
  61. log.Warn("field overflow, field=%s, value=%d, field type=%s", name, i, rv.Type().Name())
  62. }
  63. rv.SetInt(int64(i))
  64. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  65. var i, e = parsefunc(value, rv, name)
  66. if e != nil {
  67. err = fmt.Errorf("field=%s, fail to convert: %s", name, e)
  68. return
  69. }
  70. if rv.OverflowUint(i) {
  71. log.Warn("field overflow, field=%s, value=%d, field type=%s", name, i, rv.Type().Name())
  72. }
  73. rv.SetUint(i)
  74. default:
  75. err = fmt.Errorf("cannot convert type:%s, kind()=%v, field=%s", rv.Type().Name(), rv.Kind(), name)
  76. }
  77. return
  78. }
  79. func (f *field) setMap(c *hrpc.Cell) (err error) {
  80. var fieldType = f.fieldValue.Type()
  81. if f.fieldValue.IsNil() {
  82. f.fieldValue.Set(reflect.MakeMap(fieldType))
  83. fieldType = f.fieldValue.Type()
  84. }
  85. var keyType = fieldType.Key()
  86. if keyType.Kind() != reflect.String {
  87. err = fmt.Errorf("cannot convert to map, only support map key: (string), but get type=%s", keyType.Name())
  88. return
  89. }
  90. var val = reflect.Indirect(reflect.New(fieldType.Elem()))
  91. err = setBasicValue(c.Value, val, f.name, f.parser.ParseIntFunc)
  92. if err != nil {
  93. err = fmt.Errorf("cannot convert to map, only support map value: (integer, string), type=%s, err=%v", fieldType.Name(), err)
  94. return
  95. }
  96. var key = indirect(reflect.New(fieldType.Key()))
  97. key.SetString(string(c.Qualifier))
  98. f.fieldValue.SetMapIndex(key, val)
  99. return
  100. }
  101. // ParseIntFunc function to parse []byte to uint64
  102. // if not set, will assume []byte is big endian form of integer, length of 1/2/4/8 bytes
  103. type ParseIntFunc func(v []byte, rv reflect.Value, fieldname string) (result uint64, err error)
  104. //Parser parser for hbase cell
  105. type Parser struct {
  106. ParseIntFunc ParseIntFunc
  107. }
  108. func getOrCreateFieldMapByFamily(familyMap map[string]map[string]field, key string) (result map[string]field) {
  109. var ok bool
  110. if result, ok = familyMap[key]; !ok {
  111. result = make(map[string]field)
  112. familyMap[key] = result
  113. }
  114. return result
  115. }
  116. func getField(familyMap map[string]map[string]field, family string, qualifier string) (result field) {
  117. var ok bool
  118. var qualifierMap map[string]field
  119. if qualifierMap, ok = familyMap[family]; !ok {
  120. qualifierMap, ok = familyMap[""]
  121. if !ok {
  122. return
  123. }
  124. }
  125. if result, ok = qualifierMap[qualifier]; !ok {
  126. qualifierMap, ok = familyMap[""]
  127. if ok {
  128. result, ok = qualifierMap[qualifier]
  129. }
  130. if !ok {
  131. return
  132. }
  133. }
  134. return
  135. }
  136. //Parse parse cell to struct
  137. // supported type:
  138. // integer from 16 ~ 64 bit, the cell's value must be big endian form of the integer, length could be 2 or 4 or 8 bytes
  139. // string
  140. func (p *Parser) Parse(cell []*hrpc.Cell, ptr interface{}) (err error) {
  141. if len(cell) == 0 {
  142. log.Warn("cell length = 0, nothing to parse")
  143. return
  144. }
  145. var familyFieldMap = make(map[string]map[string]field)
  146. // field only have family, and type is map[string]{integer,string}
  147. var familyOnlyMap = make(map[string]field)
  148. //var noFamilyFieldMap = make(map[string]reflect.Value)
  149. var ptrType = reflect.TypeOf(ptr)
  150. // if it's ptr
  151. if ptrType.Kind() == reflect.Ptr {
  152. var value = reflect.ValueOf(ptr)
  153. value = indirect(value)
  154. var valueType = value.Type()
  155. var valueKind = valueType.Kind()
  156. if valueKind == reflect.Struct {
  157. for i := 0; i < value.NumField(); i++ {
  158. fieldInfo := valueType.Field(i) // a reflect.StructField
  159. tag := fieldInfo.Tag // a reflect.StructTag
  160. //fmt.Printf("tag for field: %s, tag: %s\n", fieldInfo.Name, tag)
  161. family := tag.Get("family")
  162. qualifier := tag.Get("qualifier")
  163. var field = field{
  164. family: family,
  165. name: fieldInfo.Name,
  166. structField: fieldInfo,
  167. fieldValue: value.Field(i),
  168. parser: p,
  169. }
  170. // if no qualifier, or star, we create only family field
  171. if qualifier == "" || qualifier == "*" {
  172. if fieldInfo.Type.Kind() != reflect.Map {
  173. log.Warn("%s.%s, family-only field only support map, but get(%s)", ptrType.Name(), fieldInfo.Name, fieldInfo.Type.Name())
  174. continue
  175. }
  176. familyOnlyMap[family] = field
  177. } else {
  178. // save field info
  179. var fieldMapForFamily = getOrCreateFieldMapByFamily(familyFieldMap, family)
  180. fieldMapForFamily[qualifier] = field
  181. }
  182. }
  183. } else {
  184. log.Warn("cannot decode, unsupport type(%s)", valueKind.String())
  185. }
  186. }
  187. if p.ParseIntFunc == nil {
  188. p.ParseIntFunc = ByteBigEndianToUint64
  189. }
  190. // parse
  191. for _, c := range cell {
  192. var family = string(c.Family)
  193. var qualifier = string(c.Qualifier)
  194. //log.Info("parse cell, family=%s, qualifier=%s", family, qualifier)
  195. var fieldValue = getField(familyFieldMap, family, qualifier)
  196. if !fieldValue.isValid() {
  197. fieldValue = familyOnlyMap[family]
  198. if !fieldValue.isValid() {
  199. //log.Warn("no field for cell, family=%s, qualifier=%s", family, qualifier)
  200. continue
  201. }
  202. }
  203. if e := fieldValue.setValue(c); e != nil {
  204. log.Warn("fail to set value, err=%v", e)
  205. continue
  206. }
  207. }
  208. return
  209. }
  210. // indirect returns the value pointed to by a pointer.
  211. // Pointers are followed until the value is not a pointer.
  212. // New values are allocated for each nil pointer.
  213. //
  214. // An exception to this rule is if the value satisfies an interface of
  215. // interest to us (like encoding.TextUnmarshaler).
  216. func indirect(v reflect.Value) reflect.Value {
  217. if v.Kind() != reflect.Ptr && v.Kind() != reflect.Interface {
  218. return v
  219. }
  220. if v.IsNil() {
  221. v.Set(reflect.New(v.Type().Elem()))
  222. } else if v.Kind() == reflect.Interface {
  223. v = v.Elem()
  224. }
  225. return indirect(reflect.Indirect(v))
  226. }
  227. //StringToUint parse string to uint
  228. func StringToUint(value []byte, rv reflect.Value, fieldname string) (result uint64, err error) {
  229. if len(value) == 0 {
  230. return
  231. }
  232. if value[0] == '-' {
  233. i64, e := strconv.ParseInt(string(value), 10, 64)
  234. err = e
  235. result = uint64(i64)
  236. } else {
  237. result, err = strconv.ParseUint(string(value), 10, 64)
  238. }
  239. return
  240. }
  241. //ByteBigEndianToUint64 convert big endian to uint64
  242. func ByteBigEndianToUint64(value []byte, rv reflect.Value, fieldname string) (result uint64, err error) {
  243. var length = len(value)
  244. switch length {
  245. case 4:
  246. result = uint64(binary.BigEndian.Uint32(value))
  247. case 8:
  248. result = uint64(binary.BigEndian.Uint64(value))
  249. case 2:
  250. result = uint64(binary.BigEndian.Uint16(value))
  251. case 1:
  252. result = uint64(value[0])
  253. default:
  254. err = fmt.Errorf("cannot decode to integer, byteslen=%d, only support (1,2,4,8)", length)
  255. }
  256. if err == nil {
  257. var vlen = len(value)
  258. var rvType = rv.Type()
  259. if rvType.Size() != uintptr(vlen) {
  260. log.Error("field=%s type=%s length=%d, cell length=%d, doesn't match, may yield wrong value!",
  261. fieldname, rvType.Name(), rvType.Size(), vlen)
  262. }
  263. }
  264. return
  265. }