@@ -3,12 +3,15 @@ package server
3
3
import (
4
4
"bytes"
5
5
"fmt"
6
+ "log"
6
7
8
+ "github.com/go-mysql-org/go-mysql/mysql"
7
9
. "github.com/go-mysql-org/go-mysql/mysql"
8
10
"github.com/go-mysql-org/go-mysql/replication"
9
11
"github.com/siddontang/go/hack"
10
12
)
11
13
14
+ // Handler is what a server needs to implement the client-server protocol
12
15
type Handler interface {
13
16
//handle COM_INIT_DB command, you can check whether the dbName is valid, or other.
14
17
UseDB (dbName string ) error
@@ -31,13 +34,16 @@ type Handler interface {
31
34
HandleOtherCommand (cmd byte , data []byte ) error
32
35
}
33
36
37
+ // ReplicationHandler is for handlers that want to implement the replication protocol
34
38
type ReplicationHandler interface {
35
39
// handle Replication command
36
40
HandleRegisterSlave (data []byte ) error
37
41
HandleBinlogDump (pos Position ) (* replication.BinlogStreamer , error )
38
42
HandleBinlogDumpGTID (gtidSet * MysqlGTIDSet ) (* replication.BinlogStreamer , error )
39
43
}
40
44
45
+ // HandleCommand is handling commands received by the server
46
+ // https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_command_phase.html
41
47
func (c * Conn ) HandleCommand () error {
42
48
if c .Conn == nil {
43
49
return fmt .Errorf ("connection closed" )
@@ -178,47 +184,101 @@ func (c *Conn) dispatch(data []byte) interface{} {
178
184
}
179
185
}
180
186
187
+ // EmptyHandler is a mostly empty implementation for demonstration purposes
181
188
type EmptyHandler struct {
182
189
}
183
190
191
+ // EmptyReplicationHandler is a empty handler that implements the replication protocol
184
192
type EmptyReplicationHandler struct {
185
193
EmptyHandler
186
194
}
187
195
196
+ // UseDB is called for COM_INIT_DB
188
197
func (h EmptyHandler ) UseDB (dbName string ) error {
198
+ log .Printf ("Received: UseDB %s" , dbName )
189
199
return nil
190
200
}
201
+
202
+ // HandleQuery is called for COM_QUERY
191
203
func (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
+
192
226
return nil , fmt .Errorf ("not supported now" )
193
227
}
194
228
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
195
232
func (h EmptyHandler ) HandleFieldList (table string , fieldWildcard string ) ([]* Field , error ) {
233
+ log .Printf ("Received: FieldList: table=%s, fieldWildcard:%s" , table , fieldWildcard )
196
234
return nil , fmt .Errorf ("not supported now" )
197
235
}
236
+
237
+ // HandleStmtPrepare is called for COM_STMT_PREPARE
198
238
func (h EmptyHandler ) HandleStmtPrepare (query string ) (int , int , interface {}, error ) {
239
+ log .Printf ("Received: StmtPrepare: %s" , query )
199
240
return 0 , 0 , nil , fmt .Errorf ("not supported now" )
200
241
}
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
201
248
func (h EmptyHandler ) HandleStmtExecute (context interface {}, query string , args []interface {}) (* Result , error ) {
249
+ log .Printf ("Received: StmtExecute: %s (args: %v)" , query , args )
202
250
return nil , fmt .Errorf ("not supported now" )
203
251
}
204
252
253
+ // HandleStmtClose is called for COM_STMT_CLOSE
205
254
func (h EmptyHandler ) HandleStmtClose (context interface {}) error {
255
+ log .Println ("Received: StmtClose" )
206
256
return nil
207
257
}
208
258
259
+ //revive:enable:unused-parameter
260
+
261
+ // HandleRegisterSlave is called for COM_REGISTER_SLAVE
209
262
func (h EmptyReplicationHandler ) HandleRegisterSlave (data []byte ) error {
263
+ log .Printf ("Received: RegisterSlave: %x" , data )
210
264
return fmt .Errorf ("not supported now" )
211
265
}
212
266
267
+ // HandleBinlogDump is called for COM_BINLOG_DUMP (non-GTID)
213
268
func (h EmptyReplicationHandler ) HandleBinlogDump (pos Position ) (* replication.BinlogStreamer , error ) {
269
+ log .Printf ("Received: BinlogDump: pos=%s" , pos .String ())
214
270
return nil , fmt .Errorf ("not supported now" )
215
271
}
216
272
273
+ // HandleBinlogDumpGTID is called for COM_BINLOG_DUMP_GTID
217
274
func (h EmptyReplicationHandler ) HandleBinlogDumpGTID (gtidSet * MysqlGTIDSet ) (* replication.BinlogStreamer , error ) {
275
+ log .Printf ("Received: BinlogDumpGTID: gtidSet=%s" , gtidSet .String ())
218
276
return nil , fmt .Errorf ("not supported now" )
219
277
}
220
278
279
+ // HandleOtherCommand is called for commands not handled elsewhere
221
280
func (h EmptyHandler ) HandleOtherCommand (cmd byte , data []byte ) error {
281
+ log .Printf ("Received: OtherCommand: cmd=%x, data=%x" , cmd , data )
222
282
return NewError (
223
283
ER_UNKNOWN_ERROR ,
224
284
fmt .Sprintf ("command %d is not supported now" , cmd ),
0 commit comments