packets.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
  2. //
  3. // Copyright 2012 Julien Schmidt. All rights reserved.
  4. // http://www.julienschmidt.com
  5. //
  6. // This Source Code Form is subject to the terms of the Mozilla Public
  7. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  8. // You can obtain one at http://mozilla.org/MPL/2.0/.
  9. package mysql
  10. import (
  11. "database/sql/driver"
  12. "errors"
  13. "fmt"
  14. "io"
  15. "time"
  16. )
  17. // Read packet to buffer 'data'
  18. func (mc *mysqlConn) readPacket() (data []byte, e error) {
  19. // Packet Length
  20. pktLen, e := mc.readNumber(3)
  21. if e != nil {
  22. return
  23. }
  24. if int(pktLen) == 0 {
  25. return
  26. }
  27. // Packet Number
  28. pktSeq, e := mc.readNumber(1)
  29. if e != nil {
  30. return
  31. }
  32. // Check Packet Sync
  33. if uint8(pktSeq) != mc.sequence {
  34. e = errors.New("Commands out of sync; you can't run this command now")
  35. return
  36. }
  37. mc.sequence++
  38. // Read rest of packet
  39. data = make([]byte, pktLen)
  40. n, e := mc.netConn.Read(data)
  41. if e != nil || n != int(pktLen) {
  42. fmt.Println(e)
  43. e = driver.ErrBadConn
  44. return
  45. }
  46. return
  47. }
  48. // Send Packet with given data
  49. func (mc *mysqlConn) writePacket(data []byte) (e error) {
  50. // Set time BEFORE to avoid possible collisions
  51. if mc.server.keepalive > 0 {
  52. mc.lastCmdTime = time.Now()
  53. }
  54. pktLen := uint32(len(data))
  55. if int(pktLen) == 0 {
  56. debug("WRITE 0 Length; ABORTING!")
  57. return
  58. }
  59. // Add the packet header
  60. pktData := make([]byte, 0, len(data)+4)
  61. pktData = append(pktData, uint24ToBytes(pktLen)...)
  62. pktData = append(pktData, mc.sequence)
  63. pktData = append(pktData, data...)
  64. // Write packet
  65. n, e := mc.netConn.Write(pktData)
  66. if e != nil || n != len(pktData) {
  67. fmt.Println("BadConn:", e)
  68. e = driver.ErrBadConn
  69. return
  70. }
  71. mc.sequence++
  72. return
  73. }
  74. // Read n bytes long number num
  75. func (mc *mysqlConn) readNumber(n uint8) (num uint64, e error) {
  76. // Read bytes into array
  77. buf := make([]byte, n)
  78. nr, err := io.ReadFull(mc.netConn, buf)
  79. if err != nil || nr != int(n) {
  80. fmt.Println(e)
  81. e = driver.ErrBadConn
  82. return
  83. }
  84. // Convert to uint64
  85. num = 0
  86. for i := uint8(0); i < n; i++ {
  87. num |= uint64(buf[i]) << (i * 8)
  88. }
  89. return
  90. }
  91. /* Handshake Initialization Packet
  92. Bytes Name
  93. ----- ----
  94. 1 protocol_version
  95. n (Null-Terminated String) server_version
  96. 4 thread_id
  97. 8 scramble_buff
  98. 1 (filler) always 0x00
  99. 2 server_capabilities
  100. 1 server_language
  101. 2 server_status
  102. 2 server capabilities (two upper bytes)
  103. 1 length of the scramble
  104. 10 (filler) always 0
  105. n rest of the plugin provided data (at least 12 bytes)
  106. 1 \0 byte, terminating the second part of a scramble
  107. */
  108. func (mc *mysqlConn) readInitPacket() (e error) {
  109. debug("Reading handshake initialization packet from server")
  110. data, e := mc.readPacket()
  111. if e != nil {
  112. return
  113. }
  114. mc.server = new(serverSettings)
  115. // Position
  116. pos := 0
  117. // Protocol version [8 bit uint]
  118. mc.server.protocol = data[pos]
  119. if mc.server.protocol < MIN_PROTOCOL_VERSION {
  120. e = errors.New(fmt.Sprintf("Unsupported MySQL Protocol Version %d. Protocol Version %d or higher is required", mc.server.protocol, MIN_PROTOCOL_VERSION))
  121. }
  122. pos++
  123. // Server version [null terminated string]
  124. slice, err := readSlice(data[pos:], 0x00)
  125. if err != nil {
  126. return
  127. }
  128. mc.server.version = string(slice)
  129. pos += len(slice) + 1
  130. // Thread id [32 bit uint]
  131. mc.server.threadID = bytesToUint32(data[pos : pos+4])
  132. pos += 4
  133. // First part of scramble buffer [8 bytes]
  134. mc.server.scrambleBuff = make([]byte, 8)
  135. mc.server.scrambleBuff = data[pos : pos+8]
  136. pos += 9
  137. // Server capabilities [16 bit uint]
  138. mc.server.flags = ClientFlag(bytesToUint16(data[pos : pos+2]))
  139. if mc.server.flags&CLIENT_PROTOCOL_41 == 0 {
  140. e = errors.New("MySQL-Server does not support required Protocol 41+")
  141. }
  142. pos += 2
  143. // Server language [8 bit uint]
  144. mc.server.charset = data[pos]
  145. pos++
  146. // Server status [16 bit uint]
  147. pos += 15
  148. mc.server.scrambleBuff = append(mc.server.scrambleBuff, data[pos:pos+12]...)
  149. return
  150. }
  151. /* Client Authentication Packet
  152. Bytes Name
  153. ----- ----
  154. 4 client_flags
  155. 4 max_packet_size
  156. 1 charset_number
  157. 23 (filler) always 0x00...
  158. n (Null-Terminated String) user
  159. n (Length Coded Binary) scramble_buff (1 + x bytes)
  160. n (Null-Terminated String) databasename (optional)
  161. */
  162. func (mc *mysqlConn) writeAuthPacket() (e error) {
  163. debug("Sending authentication packet to server")
  164. // Adjust client flags based on server support
  165. clientFlags := uint32(CLIENT_MULTI_STATEMENTS |
  166. CLIENT_MULTI_RESULTS |
  167. CLIENT_PROTOCOL_41 |
  168. CLIENT_SECURE_CONN |
  169. CLIENT_LONG_PASSWORD |
  170. CLIENT_TRANSACTIONS)
  171. if mc.server.flags&CLIENT_LONG_FLAG > 0 {
  172. clientFlags |= uint32(CLIENT_LONG_FLAG)
  173. }
  174. // To specify a db name
  175. if len(mc.cfg.dbname) > 0 {
  176. clientFlags |= uint32(CLIENT_CONNECT_WITH_DB)
  177. }
  178. // User Password
  179. scrambleBuff := scramblePassword(mc.server.scrambleBuff, []byte(mc.cfg.passwd))
  180. // Calculate packet length and make buffer with that size
  181. dataLen := 4 + 4 + 1 + 23 + len(mc.cfg.user) + 1 + 1 + len(scrambleBuff) + len(mc.cfg.dbname) + 1
  182. data := make([]byte, 0, dataLen)
  183. // ClientFlags
  184. data = append(data, uint32ToBytes(clientFlags)...)
  185. // MaxPacketSize
  186. data = append(data, uint32ToBytes(MAX_PACKET_SIZE)...)
  187. // Charset
  188. data = append(data, mc.server.charset)
  189. // Filler
  190. data = append(data, make([]byte, 23)...)
  191. // User
  192. if len(mc.cfg.user) > 0 {
  193. data = append(data, []byte(mc.cfg.user)...)
  194. }
  195. // Null-Terminator
  196. data = append(data, 0x0)
  197. // ScrambleBuffer
  198. data = append(data, byte(len(scrambleBuff)))
  199. if len(scrambleBuff) > 0 {
  200. data = append(data, scrambleBuff...)
  201. }
  202. // Databasename
  203. if len(mc.cfg.dbname) > 0 {
  204. data = append(data, []byte(mc.cfg.dbname)...)
  205. // Null-Terminator
  206. data = append(data, 0x0)
  207. }
  208. // Send Auth-Packet
  209. mc.writePacket(data)
  210. return
  211. }
  212. // Returns error if Packet is not an 'Result OK'-Packet
  213. func (mc *mysqlConn) readResultOK() (e error) {
  214. debug("Read result from server")
  215. data, e := mc.readPacket()
  216. if e != nil {
  217. return
  218. }
  219. switch data[0] {
  220. case 0:
  221. debug("OK Packet")
  222. return mc.handleOkPacket(data)
  223. case 255:
  224. debug("Error Packet")
  225. return mc.handleErrorPacket(data)
  226. default:
  227. e = errors.New("Invalid Result Packet-Type")
  228. return
  229. }
  230. return
  231. }
  232. /* Error Packet
  233. Bytes Name
  234. ----- ----
  235. 1 field_count, always = 0xff
  236. 2 errno
  237. 1 (sqlstate marker), always '#'
  238. 5 sqlstate (5 characters)
  239. n message
  240. */
  241. func (mc *mysqlConn) handleErrorPacket(data []byte) (e error) {
  242. if data[0] != 255 {
  243. e = errors.New("Wrong Packet-Type: Not an Error-Packet")
  244. return
  245. }
  246. pos := 1
  247. // Error Number [16 bit uint]
  248. errno := bytesToUint16(data[pos : pos+2])
  249. pos += 2
  250. // SQL State [# + 5bytes string]
  251. //sqlstate := string(data[pos : pos+6])
  252. pos += 6
  253. // Error Message [string]
  254. message := string(data[pos:])
  255. e = fmt.Errorf("Error %d: %s", errno, message)
  256. return
  257. }
  258. /* Ok Packet
  259. Bytes Name
  260. ----- ----
  261. 1 (Length Coded Binary) field_count, always = 0
  262. 1-9 (Length Coded Binary) affected_rows
  263. 1-9 (Length Coded Binary) insert_id
  264. 2 server_status
  265. 2 warning_count
  266. n (until end of packet) message
  267. */
  268. func (mc *mysqlConn) handleOkPacket(data []byte) (e error) {
  269. if data[0] != 0 {
  270. e = errors.New("Wrong Packet-Type: Not a OK-Packet")
  271. return
  272. }
  273. // Position
  274. pos := 1
  275. // Affected rows [Length Coded Binary]
  276. affectedRows, n, e := bytesToLengthCodedBinary(data[pos:])
  277. if e != nil {
  278. return
  279. }
  280. pos += n
  281. // Insert id [Length Coded Binary]
  282. insertID, n, e := bytesToLengthCodedBinary(data[pos:])
  283. if e != nil {
  284. return
  285. }
  286. //pos += n
  287. // Server status [16 bit uint]
  288. //serverStatus := bytesToUint16(data[pos : pos+2])
  289. //pos += 2
  290. // Warning [16 bit uint]
  291. //warningCount := bytesToUint16(data[pos : pos+2])
  292. //pos += 2
  293. //var message string
  294. // Message (optional) [string]
  295. //if pos < len(data) {
  296. // message = string(data[pos:])
  297. //}
  298. mc.affectedRows = affectedRows
  299. mc.insertId = insertID
  300. return
  301. }
  302. /* Prepare Result Packets
  303. Type Of Result Packet Hexadecimal Value Of First Byte (field_count)
  304. --------------------- ---------------------------------------------
  305. Prepare OK Packet 00
  306. Error Packet ff
  307. Prepare OK Packet
  308. Bytes Name
  309. ----- ----
  310. 1 0 - marker for OK packet
  311. 4 statement_handler_id
  312. 2 number of columns in result set
  313. 2 number of parameters in query
  314. 1 filler (always 0)
  315. 2 warning count
  316. It is made up of:
  317. a PREPARE_OK packet
  318. if "number of parameters" > 0
  319. (field packets) as in a Result Set Header Packet
  320. (EOF packet)
  321. if "number of columns" > 0
  322. (field packets) as in a Result Set Header Packet
  323. (EOF packet)
  324. */
  325. func (mc *mysqlConn) readPrepareResultPacket() (stmtID uint32, columnCount uint16, paramCount uint16, e error) {
  326. debug("Read result from server")
  327. data, e := mc.readPacket()
  328. if e != nil {
  329. return
  330. }
  331. // Position
  332. pos := 0
  333. if data[pos] != 0 {
  334. e = mc.handleErrorPacket(data)
  335. return
  336. }
  337. pos++
  338. stmtID = bytesToUint32(data[pos : pos+4])
  339. pos += 4
  340. // Column count [16 bit uint]
  341. columnCount = bytesToUint16(data[pos : pos+2])
  342. pos += 2
  343. // Param count [16 bit uint]
  344. paramCount = bytesToUint16(data[pos : pos+2])
  345. pos += 2
  346. // Warning count [16 bit uint]
  347. // bytesToUint16(data[pos : pos+2])
  348. return
  349. }
  350. /* Command Packet
  351. Bytes Name
  352. ----- ----
  353. 1 command
  354. n arg
  355. */
  356. func (mc *mysqlConn) writeCommandPacket(command commandType, args ...interface{}) (e error) {
  357. // Reset Packet Sequence
  358. mc.sequence = 0
  359. // Make slice from command byte
  360. data := []byte{byte(command)}
  361. switch command {
  362. // Commands without args
  363. case COM_QUIT, COM_PING:
  364. if len(args) > 0 {
  365. return errors.New(fmt.Sprintf("Too much arguments (Got: %d Has:0)", len(args)))
  366. }
  367. // Commands with 1 arg unterminated string
  368. case COM_QUERY, COM_STMT_PREPARE:
  369. if len(args) != 1 {
  370. return errors.New(fmt.Sprintf("Invalid arguments count (Got:%d Need: 1)", len(args)))
  371. }
  372. data = append(data, []byte(args[0].(string))...)
  373. // Commands with 1 arg 32 bit uint
  374. case COM_STMT_CLOSE:
  375. if len(args) != 1 {
  376. return errors.New(fmt.Sprintf("Invalid arguments count (Got:%d Need: 1)", len(args)))
  377. }
  378. data = append(data, uint32ToBytes(args[0].(uint32))...)
  379. default:
  380. return errors.New(fmt.Sprintf("Unknown command: %d", command))
  381. }
  382. // Send CMD packet
  383. return mc.writePacket(data)
  384. }
  385. /* Result Set Header Packet
  386. Bytes Name
  387. ----- ----
  388. 1-9 (Length-Coded-Binary) field_count
  389. 1-9 (Length-Coded-Binary) extra
  390. The order of packets for a result set is:
  391. (Result Set Header Packet) the number of columns
  392. (Field Packets) column descriptors
  393. (EOF Packet) marker: end of Field Packets
  394. (Row Data Packets) row contents
  395. (EOF Packet) marker: end of Data Packets
  396. */
  397. func (mc *mysqlConn) readResultSetHeaderPacket() (fieldCount int, e error) {
  398. debug("Read Result Set Header Packet from server")
  399. data, e := mc.readPacket()
  400. if e != nil {
  401. e = driver.ErrBadConn
  402. return
  403. }
  404. if data[0] == 255 {
  405. e = mc.handleErrorPacket(data)
  406. return
  407. } else if data[0] == 0 {
  408. e = mc.handleOkPacket(data)
  409. return
  410. }
  411. num, n, e := bytesToLengthCodedBinary(data)
  412. if e != nil || (n-len(data)) != 0 {
  413. e = errors.New("Malformed Packet")
  414. return
  415. }
  416. fieldCount = int(num)
  417. return
  418. }
  419. /* Parameter Packet
  420. Bytes Name
  421. ----- ----
  422. 2 type
  423. 2 flags
  424. 1 decimals
  425. 4 length
  426. */
  427. // Read Packets as Field Packets until EOF-Packet or an Error appears
  428. /*func (mc *mysqlConn) readParams(n int) (params []*mysqlField, e error) {
  429. debug("Reading Params")
  430. var data []byte
  431. for {
  432. data, e = mc.readPacket()
  433. if e != nil {
  434. return
  435. }
  436. // EOF Packet
  437. if data[0] == 254 && len(data) == 5 {
  438. if len(params) != n {
  439. e = errors.New(fmt.Sprintf("ParamsCount mismatch n:%d len:%d", n, len(params)))
  440. }
  441. return
  442. }
  443. var pos int
  444. // Field type [byte]
  445. fieldType := data[pos : pos+2]
  446. pos += 2
  447. // Flags [16 bit uint]
  448. flags := bytesToUint16(data[pos : pos+2])
  449. pos += 2
  450. // Decimals [8 bit uint]
  451. decimals := data[pos]
  452. pos++
  453. // Length [32 bit uint]
  454. length := bytesToUint32(data[pos : pos+4])
  455. pos += 4
  456. fmt.Printf("length=%d fieldType=%d flags=%d decimals=%d \n", length, fieldType, flags, decimals)
  457. params = append(params, &mysqlField{})
  458. //params = append(params, &mysqlField{name: name, fieldType: fieldType1})
  459. }
  460. return
  461. }*/
  462. // Read Packets as Field Packets until EOF-Packet or an Error appears
  463. func (mc *mysqlConn) readColumns(n int) (columns []*mysqlField, e error) {
  464. debug("Reading Columns")
  465. var data []byte
  466. for {
  467. data, e = mc.readPacket()
  468. if e != nil {
  469. return
  470. }
  471. // EOF Packet
  472. if data[0] == 254 && len(data) == 5 {
  473. if len(columns) != n {
  474. e = errors.New(fmt.Sprintf("ColumnsCount mismatch n:%d len:%d", n, len(columns)))
  475. }
  476. return
  477. }
  478. var pos, n int
  479. var catalog, database, table, orgTable, name, orgName []byte
  480. var defaultVal uint64
  481. // Catalog
  482. catalog, n, _, e = readLengthCodedBinary(data)
  483. if e != nil {
  484. return
  485. }
  486. pos += n
  487. // Database [len coded string]
  488. database, n, _, e = readLengthCodedBinary(data[pos:])
  489. if e != nil {
  490. return
  491. }
  492. pos += n
  493. // Table [len coded string]
  494. table, n, _, e = readLengthCodedBinary(data[pos:])
  495. if e != nil {
  496. return
  497. }
  498. pos += n
  499. // Original table [len coded string]
  500. orgTable, n, _, e = readLengthCodedBinary(data[pos:])
  501. if e != nil {
  502. return
  503. }
  504. pos += n
  505. // Name [len coded string]
  506. name, n, _, e = readLengthCodedBinary(data[pos:])
  507. if e != nil {
  508. return
  509. }
  510. pos += n
  511. // Original name [len coded string]
  512. orgName, n, _, e = readLengthCodedBinary(data[pos:])
  513. if e != nil {
  514. return
  515. }
  516. pos += n
  517. // Filler
  518. pos++
  519. // Charset [16 bit uint]
  520. charsetNumber := bytesToUint16(data[pos : pos+2])
  521. pos += 2
  522. // Length [32 bit uint]
  523. length := bytesToUint32(data[pos : pos+4])
  524. pos += 4
  525. // Field type [byte]
  526. fieldType := FieldType(data[pos])
  527. pos++
  528. // Flags [16 bit uint]
  529. flags := FieldFlag(bytesToUint16(data[pos : pos+2]))
  530. pos += 2
  531. // Decimals [8 bit uint]
  532. decimals := data[pos]
  533. pos++
  534. // Default value [len coded binary]
  535. if pos < len(data) {
  536. defaultVal, _, e = bytesToLengthCodedBinary(data[pos:])
  537. }
  538. fmt.Printf("catalog=%s database=%s table=%s orgTable=%s name=%s orgName=%s charsetNumber=%d length=%d fieldType=%d flags=%d decimals=%d defaultVal=%d \n", catalog, database, table, orgTable, name, orgName, charsetNumber, length, fieldType, flags, decimals, defaultVal)
  539. columns = append(columns, &mysqlField{name: string(name), fieldType: fieldType, flags: flags})
  540. }
  541. return
  542. }
  543. // Read Packets as Field Packets until EOF-Packet or an Error appears
  544. func (mc *mysqlConn) readRows(columnsCount int) (rows []*[]*[]byte, e error) {
  545. debug("Reading Rows")
  546. var data []byte
  547. var i, pos, n int
  548. var isNull bool
  549. for {
  550. data, e = mc.readPacket()
  551. if e != nil {
  552. return
  553. }
  554. // EOF Packet
  555. if data[0] == 254 && len(data) == 5 {
  556. return
  557. }
  558. // RowSet Packet
  559. row := make([]*[]byte, 0, columnsCount)
  560. pos = 0
  561. for i = 0; i < columnsCount; i++ {
  562. // Read bytes and convert to string
  563. var value []byte
  564. value, n, isNull, e = readLengthCodedBinary(data[pos:])
  565. if e != nil {
  566. return
  567. }
  568. // Append nil if field is NULL
  569. if isNull {
  570. row = append(row, nil)
  571. } else {
  572. row = append(row, &value)
  573. }
  574. pos += n
  575. }
  576. rows = append(rows, &row)
  577. }
  578. mc.affectedRows = uint64(len(rows))
  579. return
  580. }
  581. func (mc *mysqlConn) readBinaryRows(rc *rowsContent) (e error) {
  582. debug("Reading Rows")
  583. var data, nullBitMap []byte
  584. var i, pos, n int
  585. var unsigned, isNull bool
  586. columnsCount := len(rc.columns)
  587. for {
  588. data, e = mc.readPacket()
  589. if e != nil {
  590. return
  591. }
  592. pos = 0
  593. // EOF Packet
  594. if data[pos] == 254 && len(data) == 5 {
  595. return
  596. }
  597. pos++
  598. // BinaryRowSet Packet
  599. row := make([]*[]byte, columnsCount)
  600. nullBitMap = data[pos : pos+(columnsCount+7+2)/8]
  601. pos += (columnsCount + 7 + 2) / 8
  602. for i = 0; i < columnsCount; i++ {
  603. // Field is NULL
  604. if (nullBitMap[(i+2)/8] >> uint((i+2)%8) & 1) == 1 {
  605. row[i] = nil
  606. continue
  607. }
  608. unsigned = rc.columns[i].flags&FLAG_UNSIGNED != 0
  609. // Convert to byte-coded string
  610. switch rc.columns[i].fieldType {
  611. case FIELD_TYPE_NULL:
  612. row[i] = nil
  613. // Numeric Typs
  614. case FIELD_TYPE_TINY:
  615. if unsigned {
  616. row[i] = uintToByteStr(uint64(byteToUint8(data[pos])))
  617. } else {
  618. row[i] = intToByteStr(int64(int8(byteToUint8(data[pos]))))
  619. }
  620. pos++
  621. fmt.Println("TINY", string(*row[i]))
  622. case FIELD_TYPE_SHORT, FIELD_TYPE_YEAR:
  623. if unsigned {
  624. row[i] = uintToByteStr(uint64(bytesToUint16(data[pos : pos+2])))
  625. } else {
  626. row[i] = intToByteStr(int64(int16(bytesToUint16(data[pos : pos+2]))))
  627. }
  628. pos += 2
  629. fmt.Println("SHORT", string(*row[i]))
  630. case FIELD_TYPE_INT24, FIELD_TYPE_LONG:
  631. if unsigned {
  632. row[i] = uintToByteStr(uint64(bytesToUint32(data[pos : pos+4])))
  633. } else {
  634. row[i] = intToByteStr(int64(int32(bytesToUint32(data[pos : pos+4]))))
  635. }
  636. pos += 4
  637. fmt.Println("LONG", string(*row[i]))
  638. case FIELD_TYPE_LONGLONG:
  639. if unsigned {
  640. row[i] = uintToByteStr(bytesToUint64(data[pos : pos+8]))
  641. } else {
  642. row[i] = intToByteStr(int64(bytesToUint64(data[pos : pos+8])))
  643. }
  644. pos += 8
  645. fmt.Println("LONGLONG", string(*row[i]))
  646. case FIELD_TYPE_FLOAT:
  647. row[i] = float32ToByteStr(bytesToFloat32(data[pos : pos+4]))
  648. pos += 4
  649. fmt.Println("FLOAT", string(*row[i]))
  650. case FIELD_TYPE_DOUBLE:
  651. row[i] = float64ToByteStr(bytesToFloat64(data[pos : pos+8]))
  652. pos += 8
  653. fmt.Println("DOUBLE", string(*row[i]))
  654. case FIELD_TYPE_DECIMAL, FIELD_TYPE_NEWDECIMAL:
  655. var tmp []byte
  656. tmp, n, isNull, e = readLengthCodedBinary(data[pos:])
  657. if e != nil {
  658. return
  659. }
  660. if isNull && rc.columns[i].flags&FLAG_NOT_NULL == 0 {
  661. row[i] = nil
  662. fmt.Println("DECIMAL", nil)
  663. } else {
  664. row[i] = &tmp
  665. fmt.Println("DECIMAL", string(tmp))
  666. }
  667. pos += n
  668. // Length coded Binary Strings
  669. case FIELD_TYPE_VARCHAR, FIELD_TYPE_BIT, FIELD_TYPE_ENUM,
  670. FIELD_TYPE_SET, FIELD_TYPE_TINY_BLOB, FIELD_TYPE_MEDIUM_BLOB,
  671. FIELD_TYPE_LONG_BLOB, FIELD_TYPE_BLOB, FIELD_TYPE_VAR_STRING,
  672. FIELD_TYPE_STRING, FIELD_TYPE_GEOMETRY:
  673. var tmp []byte
  674. tmp, n, isNull, e = readLengthCodedBinary(data[pos:])
  675. if e != nil {
  676. return
  677. }
  678. if isNull && rc.columns[i].flags&FLAG_NOT_NULL == 0 {
  679. row[i] = nil
  680. fmt.Println("STRING", nil)
  681. } else {
  682. row[i] = &tmp
  683. fmt.Println("STRING", string(tmp))
  684. }
  685. pos += n
  686. // Date YYYY-MM-DD
  687. case FIELD_TYPE_DATE, FIELD_TYPE_NEWDATE:
  688. var num uint64
  689. num, n, e = bytesToLengthCodedBinary(data[pos:])
  690. if e != nil {
  691. return
  692. }
  693. pos += n
  694. var tmp []byte
  695. if num == 0 {
  696. tmp = []byte("0000-00-00")
  697. } else {
  698. tmp = []byte(fmt.Sprintf("%04d-%02d-%02d",
  699. bytesToUint16(data[pos:pos+2]),
  700. data[pos+2],
  701. data[pos+3]))
  702. }
  703. row[i] = &tmp
  704. pos += int(num)
  705. fmt.Println("DATE", string(*row[i]))
  706. // Time HH:MM:SS
  707. case FIELD_TYPE_TIME:
  708. var num uint64
  709. num, n, e = bytesToLengthCodedBinary(data[pos:])
  710. if e != nil {
  711. return
  712. }
  713. var tmp []byte
  714. if num == 0 {
  715. tmp = []byte("00:00:00")
  716. } else {
  717. tmp = []byte(fmt.Sprintf("%02d:%02d:%02d",
  718. data[pos+6],
  719. data[pos+7],
  720. data[pos+8]))
  721. }
  722. row[i] = &tmp
  723. pos += n + int(num)
  724. fmt.Println("TIME", string(*row[i]))
  725. // Timestamp YYYY-MM-DD HH:MM:SS
  726. case FIELD_TYPE_TIMESTAMP, FIELD_TYPE_DATETIME:
  727. var num uint64
  728. num, n, e = bytesToLengthCodedBinary(data[pos:])
  729. if e != nil {
  730. return
  731. }
  732. pos += n
  733. var tmp []byte
  734. if num == 0 {
  735. tmp = []byte("0000-00-00 00:00:00")
  736. } else {
  737. tmp = []byte(fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d",
  738. bytesToUint16(data[pos:pos+2]),
  739. data[pos+2],
  740. data[pos+3],
  741. data[pos+4],
  742. data[pos+5],
  743. data[pos+6]))
  744. }
  745. row[i] = &tmp
  746. pos += int(num)
  747. fmt.Println("DATE", string(*row[i]))
  748. // Please report if this happens!
  749. default:
  750. return fmt.Errorf("Unknown FieldType %d", rc.columns[i].fieldType)
  751. }
  752. }
  753. rc.rows = append(rc.rows, &row)
  754. }
  755. mc.affectedRows = uint64(len(rc.rows))
  756. return
  757. }
  758. // Reads Packets Packets until EOF-Packet or an Error appears. Returns count of Packets read
  759. func (mc *mysqlConn) readUntilEOF() (count uint64, e error) {
  760. debug("Reading Until EOF")
  761. var data []byte
  762. for {
  763. data, e = mc.readPacket()
  764. if e != nil {
  765. return
  766. }
  767. // EOF Packet
  768. if data[0] == 254 && len(data) == 5 {
  769. return
  770. }
  771. count++
  772. }
  773. return
  774. }