-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
server: DBeaver hangs on SELECT DATABASE() response #985
Comments
Tested with DBeaver CE 24.3.4.202502021521 and MySQL Connector/J 8.2.0 |
So this isn't a bug. The example is only setup to handle a single connection and DBeaver uses multiple. It works with this code: package main
import (
"fmt"
"net"
"strings"
"github.com/go-mysql-org/go-mysql/client"
"github.com/go-mysql-org/go-mysql/mysql"
"github.com/go-mysql-org/go-mysql/server"
)
type ServerHandler struct {
Conn *client.Conn
}
type Config struct {
Host string
Port int
User string
Password string
}
func NewServerHandler(cfg Config) (*ServerHandler, error) {
conn, err := client.Connect(fmt.Sprintf("%s:%d", cfg.Host, cfg.Port), cfg.User, cfg.Password, "")
if err != nil {
return nil, err
}
if err = conn.Ping(); err != nil {
return nil, err
}
return &ServerHandler{
Conn: conn,
}, nil
}
func (h ServerHandler) UseDB(dbName string) error {
return h.Conn.UseDB(dbName)
}
func (h ServerHandler) HandleQuery(query string) (*mysql.Result, error) {
res, err := h.Conn.Execute(query)
// SET doesn't seem to work due to EOF/OK differences
if strings.Contains(query, `SET NAMES`) {
return nil, nil
}
if strings.Contains(query, `set autocommit=0`) {
return nil, nil
}
return res, err
}
func (h ServerHandler) HandleFieldList(table string, fieldWildcard string) ([]*mysql.Field, error) {
return h.Conn.FieldList(table, fieldWildcard)
}
func (h ServerHandler) HandleStmtPrepare(query string) (int, int, interface{}, error) {
stmt, err := h.Conn.Prepare(query)
if err != nil {
return 0, 0, nil, err
}
return stmt.ParamNum(), stmt.ColumnNum(), stmt, nil
}
func (h ServerHandler) HandleStmtExecute(context interface{}, query string, args []interface{}) (*mysql.Result, error) {
return context.(*client.Stmt).Execute(args...)
}
func (h ServerHandler) HandleStmtClose(context interface{}) error {
return context.(*client.Stmt).Close()
}
func (h ServerHandler) HandleOtherCommand(cmd byte, data []byte) error {
return mysql.NewError(
mysql.ER_UNKNOWN_ERROR,
fmt.Sprintf("command %d is not supported now", cmd),
)
}
func handleCon(c net.Conn) {
cfg := Config{
Host: "127.0.0.1",
Port: 3306,
User: "root",
}
sh, err := NewServerHandler(cfg)
if err != nil {
panic(err)
}
conn, err := server.NewConn(c, "root", "", sh)
if err != nil {
panic(err)
}
for {
if err := conn.HandleCommand(); err != nil {
if strings.Contains(err.Error(), "connection closed") {
continue
}
panic(err)
}
}
}
func main() {
l, err := net.Listen("tcp", "127.0.0.1:4000")
if err != nil {
panic(err)
}
for {
c, err := l.Accept()
if err != nil {
panic(err)
}
go handleCon(c)
}
} Things that we might consider to change:
|
With this I was also able to run |
Though I'm new to the underlying processes of mysql. i'm happy to try implementing one of these ways forward. I assume with approach one, the work should be done in the server package? |
The example I posted in here works. The example in the readme doesn't as that only handles a single connection |
Originally posted by @matttm in #915
The text was updated successfully, but these errors were encountered: