field.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. package mysql
  2. import (
  3. "encoding/binary"
  4. )
  5. type FieldData []byte
  6. type Field struct {
  7. Data FieldData
  8. Schema []byte
  9. Table []byte
  10. OrgTable []byte
  11. Name []byte
  12. OrgName []byte
  13. Charset uint16
  14. ColumnLength uint32
  15. Type uint8
  16. Flag uint16
  17. Decimal uint8
  18. DefaultValueLength uint64
  19. DefaultValue []byte
  20. }
  21. func (p FieldData) Parse() (f *Field, err error) {
  22. f = new(Field)
  23. f.Data = p
  24. var n int
  25. pos := 0
  26. //skip catelog, always def
  27. n, err = SkipLengthEnodedString(p)
  28. if err != nil {
  29. return
  30. }
  31. pos += n
  32. //schema
  33. f.Schema, _, n, err = LengthEnodedString(p[pos:])
  34. if err != nil {
  35. return
  36. }
  37. pos += n
  38. //table
  39. f.Table, _, n, err = LengthEnodedString(p[pos:])
  40. if err != nil {
  41. return
  42. }
  43. pos += n
  44. //org_table
  45. f.OrgTable, _, n, err = LengthEnodedString(p[pos:])
  46. if err != nil {
  47. return
  48. }
  49. pos += n
  50. //name
  51. f.Name, _, n, err = LengthEnodedString(p[pos:])
  52. if err != nil {
  53. return
  54. }
  55. pos += n
  56. //org_name
  57. f.OrgName, _, n, err = LengthEnodedString(p[pos:])
  58. if err != nil {
  59. return
  60. }
  61. pos += n
  62. //skip oc
  63. pos += 1
  64. //charset
  65. f.Charset = binary.LittleEndian.Uint16(p[pos:])
  66. pos += 2
  67. //column length
  68. f.ColumnLength = binary.LittleEndian.Uint32(p[pos:])
  69. pos += 4
  70. //type
  71. f.Type = p[pos]
  72. pos++
  73. //flag
  74. f.Flag = binary.LittleEndian.Uint16(p[pos:])
  75. pos += 2
  76. //decimals 1
  77. f.Decimal = p[pos]
  78. pos++
  79. //filter [0x00][0x00]
  80. pos += 2
  81. f.DefaultValue = nil
  82. //if more data, command was field list
  83. if len(p) > pos {
  84. //length of default value lenenc-int
  85. f.DefaultValueLength, _, n = LengthEncodedInt(p[pos:])
  86. pos += n
  87. if pos+int(f.DefaultValueLength) > len(p) {
  88. err = ErrMalformPacket
  89. return
  90. }
  91. //default value string[$len]
  92. f.DefaultValue = p[pos:(pos + int(f.DefaultValueLength))]
  93. }
  94. return
  95. }
  96. func (f *Field) Dump() []byte {
  97. if f == nil {
  98. f = &Field{}
  99. }
  100. if f.Data != nil {
  101. return []byte(f.Data)
  102. }
  103. l := len(f.Schema) + len(f.Table) + len(f.OrgTable) + len(f.Name) + len(f.OrgName) + len(f.DefaultValue) + 48
  104. data := make([]byte, 0, l)
  105. data = append(data, PutLengthEncodedString([]byte("def"))...)
  106. data = append(data, PutLengthEncodedString(f.Schema)...)
  107. data = append(data, PutLengthEncodedString(f.Table)...)
  108. data = append(data, PutLengthEncodedString(f.OrgTable)...)
  109. data = append(data, PutLengthEncodedString(f.Name)...)
  110. data = append(data, PutLengthEncodedString(f.OrgName)...)
  111. data = append(data, 0x0c)
  112. data = append(data, Uint16ToBytes(f.Charset)...)
  113. data = append(data, Uint32ToBytes(f.ColumnLength)...)
  114. data = append(data, f.Type)
  115. data = append(data, Uint16ToBytes(f.Flag)...)
  116. data = append(data, f.Decimal)
  117. data = append(data, 0, 0)
  118. if f.DefaultValue != nil {
  119. data = append(data, Uint64ToBytes(f.DefaultValueLength)...)
  120. data = append(data, f.DefaultValue...)
  121. }
  122. return data
  123. }