func (c *Conn) dispatch(data []byte) error { cmd := data[0] data = data[1:] log.Debug(c.connectionId, cmd, hack.String(data)) c.lastCmd = hack.String(data) token := c.server.GetToken() c.server.GetRWlock().RLock() defer func() { c.server.GetRWlock().RUnlock() c.server.ReleaseToken(token) }() c.server.IncCounter(mysql.MYSQL_COMMAND(cmd).String()) switch mysql.MYSQL_COMMAND(cmd) { case mysql.COM_QUIT: c.Close() return nil case mysql.COM_QUERY: return c.handleQuery(hack.String(data)) case mysql.COM_PING: return c.writeOkFlush(nil) case mysql.COM_INIT_DB: log.Debug(cmd, hack.String(data)) if err := c.useDB(hack.String(data)); err != nil { return errors.Trace(err) } return c.writeOkFlush(nil) case mysql.COM_FIELD_LIST: return c.handleFieldList(data) case mysql.COM_STMT_PREPARE: // not support server side prepare yet case mysql.COM_STMT_EXECUTE: log.Fatal("not support", data) case mysql.COM_STMT_CLOSE: return c.handleStmtClose(data) case mysql.COM_STMT_SEND_LONG_DATA: log.Fatal("not support", data) case mysql.COM_STMT_RESET: log.Fatal("not support", data) default: msg := fmt.Sprintf("command %d not supported now", cmd) return mysql.NewError(mysql.ER_UNKNOWN_ERROR, msg) } return nil }
func (c *Conn) writeError(e error) error { var m *mysql.SqlError var ok bool if m, ok = e.(*mysql.SqlError); !ok { m = mysql.NewError(mysql.ER_UNKNOWN_ERROR, e.Error()) } data := make([]byte, 4, 16+len(m.Message)) data = append(data, mysql.ERR_HEADER) data = append(data, byte(m.Code), byte(m.Code>>8)) if c.capability&mysql.CLIENT_PROTOCOL_41 > 0 { data = append(data, '#') data = append(data, m.State...) } data = append(data, m.Message...) err := c.writePacket(data) if err != nil { return errors.Trace(err) } return errors.Trace(c.flush()) }