func (dc *DirectConnection) readPacket() ([]byte, error) {
	data, err := dc.conn.ReadPacket()
	dc.pkgErr = err
	return data, err
}
readPacket doesn't use EphemeralBuffer
package backend
import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"net"
	"strings"
	"github.com/nooncall/shazam/log"
	"github.com/nooncall/shazam/mysql"
	"github.com/nooncall/shazam/util/sync2"
)
type DirectConnection struct {
	conn *mysql.Conn
	addr     string
	user     string
	password string
	db       string
	capability uint32
	sessionVariables *mysql.SessionVariables
	status uint16
	collation mysql.CollationID
	charset   string
	salt      []byte
	defaultCollation mysql.CollationID
	defaultCharset   string
	pkgErr error
	closed sync2.AtomicBool
}
func NewDirectConnection(addr string, user string, password string, db string, charset string, collationID mysql.CollationID) (*DirectConnection, error) {
	dc := &DirectConnection{
		addr:             addr,
		user:             user,
		password:         password,
		db:               db,
		charset:          charset,
		collation:        collationID,
		defaultCharset:   charset,
		defaultCollation: collationID,
		closed:           sync2.NewAtomicBool(false),
		sessionVariables: mysql.NewSessionVariables(),
	}
	err := dc.connect()
	return dc, err
}
func (dc *DirectConnection) connect() error {
	if dc.conn != nil {
		dc.conn.Close()
	}
	typ := "tcp"
	if strings.Contains(dc.addr, "/") {
		typ = "unix"
	}
	netConn, err := net.Dial(typ, dc.addr)
	if err != nil {
		return err
	}
	tcpConn := netConn.(*net.TCPConn)
	tcpConn.SetNoDelay(true)
	tcpConn.SetKeepAlive(true)
	dc.conn = mysql.NewConn(tcpConn)
	if err := dc.readInitialHandshake(); err != nil {
		dc.conn.Close()
		return err
	}
	if err := dc.writeHandshakeResponse41(); err != nil {
		dc.conn.Close()
		return err
	}
	response, err := dc.readPacket()
	if err != nil {
		dc.conn.Close()
		return err
	}
	switch response[0] {
	case mysql.OKHeader:
	default:
		return errors.New("dc connection handshake failed with mysql")
	}
	if !dc.IsAutoCommit() {
		if _, err := dc.exec("set autocommit = 1"); err != nil {
			dc.conn.Close()
			return err
		}
	}
	return nil
}
func (dc *DirectConnection) Close() {
	if dc.conn != nil {
		dc.conn.Close()
	}
	dc.conn = nil
	dc.salt = nil
	dc.pkgErr = nil
	dc.closed.Set(true)
	return
}
func (dc *DirectConnection) IsClosed() bool {
	return dc.closed.Get()
}