field.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package mysql
  2. import (
  3. "encoding/binary"
  4. "github.com/go-mysql-org/go-mysql/utils"
  5. )
  6. type FieldData []byte
  7. type Field struct {
  8. Data FieldData
  9. Schema []byte
  10. Table []byte
  11. OrgTable []byte
  12. Name []byte
  13. OrgName []byte
  14. Charset uint16
  15. ColumnLength uint32
  16. Type uint8
  17. Flag uint16
  18. Decimal uint8
  19. DefaultValueLength uint64
  20. DefaultValue []byte
  21. }
  22. type FieldValueType uint8
  23. type FieldValue struct {
  24. Type FieldValueType
  25. value uint64 // Also for int64 and float64
  26. str []byte
  27. }
  28. const (
  29. FieldValueTypeNull = iota
  30. FieldValueTypeUnsigned
  31. FieldValueTypeSigned
  32. FieldValueTypeFloat
  33. FieldValueTypeString
  34. )
  35. func (f *Field) Parse(p FieldData) (err error) {
  36. f.Data = p
  37. var n int
  38. pos := 0
  39. //skip catelog, always def
  40. n, err = SkipLengthEncodedString(p)
  41. if err != nil {
  42. return
  43. }
  44. pos += n
  45. //schema
  46. f.Schema, _, n, err = LengthEncodedString(p[pos:])
  47. if err != nil {
  48. return
  49. }
  50. pos += n
  51. //table
  52. f.Table, _, n, err = LengthEncodedString(p[pos:])
  53. if err != nil {
  54. return
  55. }
  56. pos += n
  57. //org_table
  58. f.OrgTable, _, n, err = LengthEncodedString(p[pos:])
  59. if err != nil {
  60. return
  61. }
  62. pos += n
  63. //name
  64. f.Name, _, n, err = LengthEncodedString(p[pos:])
  65. if err != nil {
  66. return
  67. }
  68. pos += n
  69. //org_name
  70. f.OrgName, _, n, err = LengthEncodedString(p[pos:])
  71. if err != nil {
  72. return
  73. }
  74. pos += n
  75. //skip oc
  76. pos += 1
  77. //charset
  78. f.Charset = binary.LittleEndian.Uint16(p[pos:])
  79. pos += 2
  80. //column length
  81. f.ColumnLength = binary.LittleEndian.Uint32(p[pos:])
  82. pos += 4
  83. //type
  84. f.Type = p[pos]
  85. pos++
  86. //flag
  87. f.Flag = binary.LittleEndian.Uint16(p[pos:])
  88. pos += 2
  89. //decimals 1
  90. f.Decimal = p[pos]
  91. pos++
  92. //filter [0x00][0x00]
  93. pos += 2
  94. f.DefaultValue = nil
  95. //if more data, command was field list
  96. if len(p) > pos {
  97. //length of default value lenenc-int
  98. f.DefaultValueLength, _, n = LengthEncodedInt(p[pos:])
  99. pos += n
  100. if pos+int(f.DefaultValueLength) > len(p) {
  101. err = ErrMalformPacket
  102. return
  103. }
  104. //default value string[$len]
  105. f.DefaultValue = p[pos:(pos + int(f.DefaultValueLength))]
  106. }
  107. return nil
  108. }
  109. func (p FieldData) Parse() (f *Field, err error) {
  110. f = new(Field)
  111. if err = f.Parse(p); err != nil {
  112. return nil, err
  113. }
  114. return f, nil
  115. }
  116. func (f *Field) Dump() []byte {
  117. if f == nil {
  118. f = &Field{}
  119. }
  120. if f.Data != nil {
  121. return []byte(f.Data)
  122. }
  123. l := len(f.Schema) + len(f.Table) + len(f.OrgTable) + len(f.Name) + len(f.OrgName) + len(f.DefaultValue) + 48
  124. data := make([]byte, 0, l)
  125. data = append(data, PutLengthEncodedString([]byte("def"))...)
  126. data = append(data, PutLengthEncodedString(f.Schema)...)
  127. data = append(data, PutLengthEncodedString(f.Table)...)
  128. data = append(data, PutLengthEncodedString(f.OrgTable)...)
  129. data = append(data, PutLengthEncodedString(f.Name)...)
  130. data = append(data, PutLengthEncodedString(f.OrgName)...)
  131. data = append(data, 0x0c)
  132. data = append(data, Uint16ToBytes(f.Charset)...)
  133. data = append(data, Uint32ToBytes(f.ColumnLength)...)
  134. data = append(data, f.Type)
  135. data = append(data, Uint16ToBytes(f.Flag)...)
  136. data = append(data, f.Decimal)
  137. data = append(data, 0, 0)
  138. if f.DefaultValue != nil {
  139. data = append(data, Uint64ToBytes(f.DefaultValueLength)...)
  140. data = append(data, f.DefaultValue...)
  141. }
  142. return data
  143. }
  144. func (fv *FieldValue) AsUint64() uint64 {
  145. return fv.value
  146. }
  147. func (fv *FieldValue) AsInt64() int64 {
  148. return utils.Uint64ToInt64(fv.value)
  149. }
  150. func (fv *FieldValue) AsFloat64() float64 {
  151. return utils.Uint64ToFloat64(fv.value)
  152. }
  153. func (fv *FieldValue) AsString() []byte {
  154. return fv.str
  155. }
  156. func (fv *FieldValue) Value() interface{} {
  157. switch fv.Type {
  158. case FieldValueTypeUnsigned:
  159. return fv.AsUint64()
  160. case FieldValueTypeSigned:
  161. return fv.AsInt64()
  162. case FieldValueTypeFloat:
  163. return fv.AsFloat64()
  164. case FieldValueTypeString:
  165. return fv.AsString()
  166. default: // FieldValueTypeNull
  167. return nil
  168. }
  169. }