@@ -3,12 +3,15 @@ package server
33import (
44 "bytes"
55 "fmt"
6+ "log"
67
8+ "github.com/go-mysql-org/go-mysql/mysql"
79 . "github.com/go-mysql-org/go-mysql/mysql"
810 "github.com/go-mysql-org/go-mysql/replication"
911 "github.com/siddontang/go/hack"
1012)
1113
14+ // Handler is what a server needs to implement the client-server protocol
1215type Handler interface {
1316 //handle COM_INIT_DB command, you can check whether the dbName is valid, or other.
1417 UseDB (dbName string ) error
@@ -31,13 +34,16 @@ type Handler interface {
3134 HandleOtherCommand (cmd byte , data []byte ) error
3235}
3336
37+ // ReplicationHandler is for handlers that want to implement the replication protocol
3438type ReplicationHandler interface {
3539 // handle Replication command
3640 HandleRegisterSlave (data []byte ) error
3741 HandleBinlogDump (pos Position ) (* replication.BinlogStreamer , error )
3842 HandleBinlogDumpGTID (gtidSet * MysqlGTIDSet ) (* replication.BinlogStreamer , error )
3943}
4044
45+ // HandleCommand is handling commands received by the server
46+ // https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_command_phase.html
4147func (c * Conn ) HandleCommand () error {
4248 if c .Conn == nil {
4349 return fmt .Errorf ("connection closed" )
@@ -178,47 +184,101 @@ func (c *Conn) dispatch(data []byte) interface{} {
178184 }
179185}
180186
187+ // EmptyHandler is a mostly empty implementation for demonstration purposes
181188type EmptyHandler struct {
182189}
183190
191+ // EmptyReplicationHandler is a empty handler that implements the replication protocol
184192type EmptyReplicationHandler struct {
185193 EmptyHandler
186194}
187195
196+ // UseDB is called for COM_INIT_DB
188197func (h EmptyHandler ) UseDB (dbName string ) error {
198+ log .Printf ("Received: UseDB %s" , dbName )
189199 return nil
190200}
201+
202+ // HandleQuery is called for COM_QUERY
191203func (h EmptyHandler ) HandleQuery (query string ) (* Result , error ) {
204+ log .Printf ("Received: Query: %s" , query )
205+
206+ // These two queries are implemented for minimal support for MySQL Shell
207+ if query == `SET NAMES 'utf8mb4';` {
208+ return nil , nil
209+ }
210+ if query == `select concat(@@version, ' ', @@version_comment)` {
211+ r , err := mysql .BuildSimpleResultset ([]string {"concat(@@version, ' ', @@version_comment)" }, [][]interface {}{
212+ {"8.0.11" },
213+ }, false )
214+ if err != nil {
215+ return nil , err
216+ }
217+ return & mysql.Result {
218+ Status : 0 ,
219+ Warnings : 0 ,
220+ InsertId : 0 ,
221+ AffectedRows : 0 ,
222+ Resultset : r ,
223+ }, nil
224+ }
225+
192226 return nil , fmt .Errorf ("not supported now" )
193227}
194228
229+ // HandleFieldList is called for COM_FIELD_LIST packets
230+ // Note that COM_FIELD_LIST has been deprecated since MySQL 5.7.11
231+ // https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_com_field_list.html
195232func (h EmptyHandler ) HandleFieldList (table string , fieldWildcard string ) ([]* Field , error ) {
233+ log .Printf ("Received: FieldList: table=%s, fieldWildcard:%s" , table , fieldWildcard )
196234 return nil , fmt .Errorf ("not supported now" )
197235}
236+
237+ // HandleStmtPrepare is called for COM_STMT_PREPARE
198238func (h EmptyHandler ) HandleStmtPrepare (query string ) (int , int , interface {}, error ) {
239+ log .Printf ("Received: StmtPrepare: %s" , query )
199240 return 0 , 0 , nil , fmt .Errorf ("not supported now" )
200241}
242+
243+ // 'context' isn't used but replacing it with `_` would remove important information for who
244+ // wants to extend this later.
245+ //revive:disable:unused-parameter
246+
247+ // HandleStmtExecute is called for COM_STMT_EXECUTE
201248func (h EmptyHandler ) HandleStmtExecute (context interface {}, query string , args []interface {}) (* Result , error ) {
249+ log .Printf ("Received: StmtExecute: %s (args: %v)" , query , args )
202250 return nil , fmt .Errorf ("not supported now" )
203251}
204252
253+ // HandleStmtClose is called for COM_STMT_CLOSE
205254func (h EmptyHandler ) HandleStmtClose (context interface {}) error {
255+ log .Println ("Received: StmtClose" )
206256 return nil
207257}
208258
259+ //revive:enable:unused-parameter
260+
261+ // HandleRegisterSlave is called for COM_REGISTER_SLAVE
209262func (h EmptyReplicationHandler ) HandleRegisterSlave (data []byte ) error {
263+ log .Printf ("Received: RegisterSlave: %x" , data )
210264 return fmt .Errorf ("not supported now" )
211265}
212266
267+ // HandleBinlogDump is called for COM_BINLOG_DUMP (non-GTID)
213268func (h EmptyReplicationHandler ) HandleBinlogDump (pos Position ) (* replication.BinlogStreamer , error ) {
269+ log .Printf ("Received: BinlogDump: pos=%s" , pos .String ())
214270 return nil , fmt .Errorf ("not supported now" )
215271}
216272
273+ // HandleBinlogDumpGTID is called for COM_BINLOG_DUMP_GTID
217274func (h EmptyReplicationHandler ) HandleBinlogDumpGTID (gtidSet * MysqlGTIDSet ) (* replication.BinlogStreamer , error ) {
275+ log .Printf ("Received: BinlogDumpGTID: gtidSet=%s" , gtidSet .String ())
218276 return nil , fmt .Errorf ("not supported now" )
219277}
220278
279+ // HandleOtherCommand is called for commands not handled elsewhere
221280func (h EmptyHandler ) HandleOtherCommand (cmd byte , data []byte ) error {
281+ log .Printf ("Received: OtherCommand: cmd=%x, data=%x" , cmd , data )
222282 return NewError (
223283 ER_UNKNOWN_ERROR ,
224284 fmt .Sprintf ("command %d is not supported now" , cmd ),
0 commit comments