driver.go 2.5 KB

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