Skip to content

[Question] How can I stream the results? #1054

@fansehep

Description

@fansehep

In my code:

package main

import (
	"log"
	"net"
	"time"

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

type MySQLStreamResultTestHandler struct {
	clientAddr string
	*server.Conn
}

func (h *MySQLStreamResultTestHandler) UseDB(dbName string) error {
	return nil
}

func (h *MySQLStreamResultTestHandler) HandleQuery(query string) (*mysql.Result, error) {
	log.Printf("Received query: %s from %s", query, h.clientAddr)
	if query == "show binary logs" {
		names := []string{"Log_name", "File_size"}
		values := [][]any{{"mysql-bin.001000", "123"}}
		r1, _ := mysql.BuildSimpleResultset(names, values, false)
		// r1.Streaming = mys
		r1.StreamingDone = false
		r1.Streaming = mysql.StreamingSelect

		r1result := mysql.NewResult(r1)
		h.WriteValue(r1result)

		r2, _ := mysql.BuildSimpleResultset(names, values, false)
		r2.Streaming = mysql.StreamingNone
		r2.StreamingDone = true
		r2result := mysql.NewResult(r2)
		// h.WriteValue(r2result)

		return r2result, nil
	}

	return nil, nil
}

func (h *MySQLStreamResultTestHandler) HandleFieldList(table string, fieldWildcard string) ([]*mysql.Field, error) {
	return nil, nil
}

func (h *MySQLStreamResultTestHandler) HandleStmtPrepare(query string) (params int, columns int, context interface{}, err error) {
	return 0, 0, nil, nil
}

func (h *MySQLStreamResultTestHandler) HandleStmtExecute(context interface{}, query string, args []interface{}) (*mysql.Result, error) {
	return nil, nil
}

func (h *MySQLStreamResultTestHandler) HandleStmtClose(context interface{}) error {
	return nil
}

func (h *MySQLStreamResultTestHandler) HandleOtherCommand(cmd byte, data []byte) error {
	return nil
}

func main() {

	listener, err := net.Listen("tcp", "127.0.0.1:4000")
	if err != nil {
		log.Fatalf("Failed to listen on TCP address: %v", err)
	}

	go func() {
		for {
			conn, err := listener.Accept()
			if err != nil {
				log.Fatalf("Failed to accept TCP connection: %v", err)
				return
			}

			cmdHandler := &MySQLStreamResultTestHandler{
				clientAddr: conn.RemoteAddr().String(),
			}
			mysqlConn, err := server.NewConn(conn, "root", "", cmdHandler)
			if err != nil {
				log.Fatalf("Failed to create MySQL connection: %v", err)
				return
			}
			for {
				if err := mysqlConn.HandleCommand(); err != nil {
					log.Fatal(err)
				}
			}
		}
	}()

	time.Sleep(1000 * time.Second)
}

This example will panic!

Some queries have too much data and I need to stream the Result to reduce the server-side memory footprint.
But I have a question about the use of *mysql.Result, can you provide an example that shows me how to query with Stream Result?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions