114 lines
1.7 KiB
Go
114 lines
1.7 KiB
Go
package server
|
|
|
|
import (
|
|
"net"
|
|
"sync/atomic"
|
|
|
|
. "github.com/siddontang/go-mysql/mysql"
|
|
"github.com/siddontang/go-mysql/packet"
|
|
"github.com/siddontang/go/sync2"
|
|
)
|
|
|
|
/*
|
|
Conn acts like a MySQL server connection, you can use MySQL client to communicate with it.
|
|
*/
|
|
type Conn struct {
|
|
*packet.Conn
|
|
|
|
capability uint32
|
|
|
|
connectionID uint32
|
|
|
|
status uint16
|
|
|
|
user string
|
|
|
|
salt []byte
|
|
|
|
h Handler
|
|
|
|
stmts map[uint32]*Stmt
|
|
stmtID uint32
|
|
|
|
closed sync2.AtomicBool
|
|
}
|
|
|
|
var baseConnID uint32 = 10000
|
|
|
|
func NewConn(conn net.Conn, user string, password string, h Handler) (*Conn, error) {
|
|
c := new(Conn)
|
|
|
|
c.h = h
|
|
|
|
c.user = user
|
|
c.Conn = packet.NewConn(conn)
|
|
|
|
c.connectionID = atomic.AddUint32(&baseConnID, 1)
|
|
|
|
c.stmts = make(map[uint32]*Stmt)
|
|
|
|
c.salt, _ = RandomBuf(20)
|
|
|
|
c.closed.Set(false)
|
|
|
|
if err := c.handshake(password); err != nil {
|
|
c.Close()
|
|
return nil, err
|
|
}
|
|
|
|
return c, nil
|
|
}
|
|
|
|
func (c *Conn) handshake(password string) error {
|
|
if err := c.writeInitialHandshake(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := c.readHandshakeResponse(password); err != nil {
|
|
c.writeError(err)
|
|
|
|
return err
|
|
}
|
|
|
|
if err := c.writeOK(nil); err != nil {
|
|
return err
|
|
}
|
|
|
|
c.ResetSequence()
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *Conn) Close() {
|
|
c.closed.Set(true)
|
|
c.Conn.Close()
|
|
}
|
|
|
|
func (c *Conn) Closed() bool {
|
|
return c.closed.Get()
|
|
}
|
|
|
|
func (c *Conn) GetUser() string {
|
|
return c.user
|
|
}
|
|
|
|
func (c *Conn) ConnectionID() uint32 {
|
|
return c.connectionID
|
|
}
|
|
|
|
func (c *Conn) IsAutoCommit() bool {
|
|
return c.status&SERVER_STATUS_AUTOCOMMIT > 0
|
|
}
|
|
|
|
func (c *Conn) IsInTransaction() bool {
|
|
return c.status&SERVER_STATUS_IN_TRANS > 0
|
|
}
|
|
|
|
func (c *Conn) SetInTransaction() {
|
|
c.status |= SERVER_STATUS_IN_TRANS
|
|
}
|
|
|
|
func (c *Conn) ClearInTransaction() {
|
|
c.status &= ^SERVER_STATUS_IN_TRANS
|
|
}
|