Connect implements driver.Connector interface. Connect returns a connection to the database.
(ctx context.Context)
| 65 | // Connect implements driver.Connector interface. |
| 66 | // Connect returns a connection to the database. |
| 67 | func (c *connector) Connect(ctx context.Context) (driver.Conn, error) { |
| 68 | var err error |
| 69 | |
| 70 | // Invoke beforeConnect if present, with a copy of the configuration |
| 71 | cfg := c.cfg |
| 72 | if c.cfg.beforeConnect != nil { |
| 73 | cfg = c.cfg.Clone() |
| 74 | err = c.cfg.beforeConnect(ctx, cfg) |
| 75 | if err != nil { |
| 76 | return nil, err |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | // New mysqlConn |
| 81 | mc := &mysqlConn{ |
| 82 | maxAllowedPacket: maxPacketSize, |
| 83 | maxWriteSize: maxPacketSize - 1, |
| 84 | closech: make(chan struct{}), |
| 85 | cfg: cfg, |
| 86 | connector: c, |
| 87 | } |
| 88 | mc.parseTime = mc.cfg.ParseTime |
| 89 | |
| 90 | // Connect to Server |
| 91 | dctx := ctx |
| 92 | if mc.cfg.Timeout > 0 { |
| 93 | var cancel context.CancelFunc |
| 94 | dctx, cancel = context.WithTimeout(ctx, c.cfg.Timeout) |
| 95 | defer cancel() |
| 96 | } |
| 97 | |
| 98 | if c.cfg.DialFunc != nil { |
| 99 | mc.netConn, err = c.cfg.DialFunc(dctx, mc.cfg.Net, mc.cfg.Addr) |
| 100 | } else { |
| 101 | dialsLock.RLock() |
| 102 | dial, ok := dials[mc.cfg.Net] |
| 103 | dialsLock.RUnlock() |
| 104 | if ok { |
| 105 | mc.netConn, err = dial(dctx, mc.cfg.Addr) |
| 106 | } else { |
| 107 | nd := net.Dialer{} |
| 108 | mc.netConn, err = nd.DialContext(dctx, mc.cfg.Net, mc.cfg.Addr) |
| 109 | } |
| 110 | } |
| 111 | if err != nil { |
| 112 | return nil, err |
| 113 | } |
| 114 | mc.rawConn = mc.netConn |
| 115 | |
| 116 | // Enable TCP Keepalives on TCP connections |
| 117 | if tc, ok := mc.netConn.(*net.TCPConn); ok { |
| 118 | if err := tc.SetKeepAlive(true); err != nil { |
| 119 | c.cfg.Logger.Print(err) |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | // Call startWatcher for context support (From Go 1.8) |
| 124 | mc.startWatcher() |