Skip to content

Commit

Permalink
server: Improve example
Browse files Browse the repository at this point in the history
1. Use the example from the `README.md` and turn it into
   a `go-mysqlserver` binary that users can run.
2. Add more logging to make it easier to understand what it is doing.
   This is done both in `go-mysqlserver` as well as the `EmptyHandler`
3. Remove the `server/example` as we already have a example now.
4. Support the minimal set of queries that MySQL Shell `mysqlsh` needs
   to be able to connect. (tested with MySQL Shell 9.1.0)
5. Change the default version from 5.7.0 to 8.0.11 (first 8.0 GA
   version)
  • Loading branch information
dveeden committed Oct 27, 2024
1 parent dcd3669 commit 96f761a
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 57 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ build:
${GO} build -o bin/go-mysqldump cmd/go-mysqldump/main.go
${GO} build -o bin/go-canal cmd/go-canal/main.go
${GO} build -o bin/go-binlogparser cmd/go-binlogparser/main.go
${GO} build -o bin/go-mysqlserver cmd/go-mysqlserver/main.go

test:
${GO} test --race -timeout 2m ./...
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,6 @@ func main() {
}
}
}

```

Another shell
Expand Down
44 changes: 44 additions & 0 deletions cmd/go-mysqlserver/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package main

import (
"log"
"net"

"github.com/go-mysql-org/go-mysql/server"
)

func main() {
// Listen for connections on localhost port 4000
l, err := net.Listen("tcp", "127.0.0.1:4000")
if err != nil {
log.Fatal(err)
}

log.Println("Listening on port 4000, connect with 'mysql -h 127.0.0.1 -P 4000 -u root'")

// Accept a new connection once
c, err := l.Accept()
if err != nil {
log.Fatal(err)
}

log.Println("Accepted connection")

// Create a connection with user root and an empty password.
// You can use your own handler to handle command here.
conn, err := server.NewConn(c, "root", "", server.EmptyHandler{})
if err != nil {
log.Fatal(err)
}

log.Println("Registered the connection with the server")

// as long as the client keeps sending commands, keep handling them
for {
if err := conn.HandleCommand(); err != nil {
log.Fatal(err)
}
}

log.Println("Connection is gone, stopping the server")
}
34 changes: 34 additions & 0 deletions server/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package server
import (
"bytes"
"fmt"
"log"

"github.com/go-mysql-org/go-mysql/mysql"
. "github.com/go-mysql-org/go-mysql/mysql"
"github.com/go-mysql-org/go-mysql/replication"
"github.com/siddontang/go/hack"
Expand Down Expand Up @@ -186,39 +188,71 @@ type EmptyReplicationHandler struct {
}

func (h EmptyHandler) UseDB(dbName string) error {
log.Printf("Received: UseDB %s", dbName)
return nil
}
func (h EmptyHandler) HandleQuery(query string) (*Result, error) {
log.Printf("Received: Query: %s", query)

// These two queries are implemented for minimal support for MySQL Shell
if query == `SET NAMES 'utf8mb4';` {
return nil, nil
}
if query == `select concat(@@version, ' ', @@version_comment)` {
r, err := mysql.BuildSimpleResultset([]string{"concat(@@version, ' ', @@version_comment)"}, [][]interface{}{
{"8.0.11"},
}, false)
if err != nil {
return nil, err
} else {
return &mysql.Result{
Status: 0,
Warnings: 0,
InsertId: 0,
AffectedRows: 0,
Resultset: r,
}, nil
}
}

return nil, fmt.Errorf("not supported now")
}

func (h EmptyHandler) HandleFieldList(table string, fieldWildcard string) ([]*Field, error) {
log.Println("Received: FieldList")
return nil, fmt.Errorf("not supported now")
}
func (h EmptyHandler) HandleStmtPrepare(query string) (int, int, interface{}, error) {
log.Printf("Received: StmtPrepare: %s", query)
return 0, 0, nil, fmt.Errorf("not supported now")
}
func (h EmptyHandler) HandleStmtExecute(context interface{}, query string, args []interface{}) (*Result, error) {
log.Println("Received: StmtExecute")
return nil, fmt.Errorf("not supported now")
}

func (h EmptyHandler) HandleStmtClose(context interface{}) error {
log.Println("Received: StmtClose")
return nil
}

func (h EmptyReplicationHandler) HandleRegisterSlave(data []byte) error {
log.Println("Received: RegisterSlave")
return fmt.Errorf("not supported now")
}

func (h EmptyReplicationHandler) HandleBinlogDump(pos Position) (*replication.BinlogStreamer, error) {
log.Println("Received: BinlogDump")
return nil, fmt.Errorf("not supported now")
}

func (h EmptyReplicationHandler) HandleBinlogDumpGTID(gtidSet *MysqlGTIDSet) (*replication.BinlogStreamer, error) {
log.Println("Received: BinlogDumpGTID")
return nil, fmt.Errorf("not supported now")
}

func (h EmptyHandler) HandleOtherCommand(cmd byte, data []byte) error {
log.Println("Received: OtherCommand")
return NewError(
ER_UNKNOWN_ERROR,
fmt.Sprintf("command %d is not supported now", cmd),
Expand Down
55 changes: 0 additions & 55 deletions server/example/server_example.go

This file was deleted.

2 changes: 1 addition & 1 deletion server/server_conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func NewDefaultServer() *Server {
certPem, keyPem := generateAndSignRSACerts(caPem, caKey)
tlsConf := NewServerTLSConfig(caPem, certPem, keyPem, tls.VerifyClientCertIfGiven)
return &Server{
serverVersion: "5.7.0",
serverVersion: "8.0.11",
protocolVersion: 10,
capability: CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB | CLIENT_PROTOCOL_41 |
CLIENT_TRANSACTIONS | CLIENT_SECURE_CONNECTION | CLIENT_PLUGIN_AUTH | CLIENT_SSL | CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA,
Expand Down

0 comments on commit 96f761a

Please sign in to comment.