driver.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Copyright 2012 Julien Schmidt. All rights reserved.
  2. // http://www.julienschmidt.com
  3. //
  4. // This Source Code Form is subject to the terms of the Mozilla Public
  5. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  6. // You can obtain one at http://mozilla.org/MPL/2.0/.
  7. // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
  8. //
  9. // The driver should be used via the database/sql package:
  10. //
  11. // import "database/sql"
  12. // import _ "github.com/go-sql-driver/mysql"
  13. //
  14. // db, err := sql.Open("mysql", "user:password@/dbname")
  15. //
  16. // See https://github.com/go-sql-driver/mysql#usage for details
  17. package mysql
  18. import (
  19. "database/sql"
  20. "database/sql/driver"
  21. "net"
  22. )
  23. // This struct is exported to make the driver directly accessible.
  24. // In general the driver is used via the database/sql package.
  25. type MySQLDriver struct{}
  26. // Open new Connection.
  27. // See https://github.com/go-sql-driver/mysql#dsn-data-source-name for how
  28. // the DSN string is formated
  29. func (d *MySQLDriver) Open(dsn string) (driver.Conn, error) {
  30. var err error
  31. // New mysqlConn
  32. mc := &mysqlConn{
  33. maxPacketAllowed: maxPacketSize,
  34. maxWriteSize: maxPacketSize - 1,
  35. }
  36. mc.cfg, err = parseDSN(dsn)
  37. if err != nil {
  38. return nil, err
  39. }
  40. // Connect to Server
  41. nd := net.Dialer{Timeout: mc.cfg.timeout}
  42. mc.netConn, err = nd.Dial(mc.cfg.net, mc.cfg.addr)
  43. if err != nil {
  44. return nil, err
  45. }
  46. mc.buf = newBuffer(mc.netConn)
  47. // Reading Handshake Initialization Packet
  48. cipher, err := mc.readInitPacket()
  49. if err != nil {
  50. mc.Close()
  51. return nil, err
  52. }
  53. // Send Client Authentication Packet
  54. if err = mc.writeAuthPacket(cipher); err != nil {
  55. mc.Close()
  56. return nil, err
  57. }
  58. // Read Result Packet
  59. err = mc.readResultOK()
  60. if err != nil {
  61. // Retry with old authentication method, if allowed
  62. if mc.cfg.allowOldPasswords && err == errOldPassword {
  63. if err = mc.writeOldAuthPacket(cipher); err != nil {
  64. mc.Close()
  65. return nil, err
  66. }
  67. if err = mc.readResultOK(); err != nil {
  68. mc.Close()
  69. return nil, err
  70. }
  71. } else {
  72. mc.Close()
  73. return nil, err
  74. }
  75. }
  76. // Get max allowed packet size
  77. maxap, err := mc.getSystemVar("max_allowed_packet")
  78. if err != nil {
  79. mc.Close()
  80. return nil, err
  81. }
  82. mc.maxPacketAllowed = stringToInt(maxap) - 1
  83. if mc.maxPacketAllowed < maxPacketSize {
  84. mc.maxWriteSize = mc.maxPacketAllowed
  85. }
  86. // Handle DSN Params
  87. err = mc.handleParams()
  88. if err != nil {
  89. mc.Close()
  90. return nil, err
  91. }
  92. return mc, nil
  93. }
  94. func init() {
  95. sql.Register("mysql", &MySQLDriver{})
  96. }