func (cdc *ChannelDriverConn) WriteQuery(query string) error {
	if cdc.conn == nil {
		return fmt.Errorf("connection closed")
	}
	m := message{
		Type:  queryMessage,
		Value: []string{query},
	}
	cdc.conn <- m
	return nil
}
WriteQuery allows client to query the RamSQL server
package protocol
import (
	"errors"
	"fmt"
	"io"
)
const (
	errMessage       = "ERR"
	queryMessage     = "QUERY"
	execMessage      = "EXEC"
	resultMessage    = "RES"
	rowHeaderMessage = "ROWHEAD"
	rowValueMessage  = "ROWVAL"
	rowEndMessage    = "ROWEND"
)
type message struct {
	Type  string
	Value []string
}
type ChannelDriverConn struct {
	conn chan message
}
type ChannelDriverEndpoint struct {
	newConnChannel chan<- chan message
}
func (cdc *ChannelDriverConn) Close() {
	if cdc.conn == nil {
		return
	}
	close(cdc.conn)
	cdc.conn = nil
}
func (cde *ChannelDriverEndpoint) New(uri string) (DriverConn, error) {
	if cde.newConnChannel == nil {
		return nil, fmt.Errorf("connection closed")
	}
	channel := make(chan message)
	cdc := &ChannelDriverConn{conn: channel}
	cde.newConnChannel <- channel
	return cdc, nil
}
func NewChannelDriverEndpoint(channel chan<- chan message) DriverEndpoint {
	cde := &ChannelDriverEndpoint{
		newConnChannel: channel,
	}
	return cde
}
type ChannelEngineEndpoint struct {
	newConnChannel <-chan chan message
}
func NewChannelEngineEndpoint(channel <-chan chan message) EngineEndpoint {
	cee := &ChannelEngineEndpoint{
		newConnChannel: channel,
	}
	return cee
}
func (cee *ChannelEngineEndpoint) Accept() (EngineConn, error) {
	newConn, ok := <-cee.newConnChannel
	if !ok {
		return nil, io.EOF
	}
	return NewChannelEngineConn(newConn), nil
}
func (cee *ChannelEngineEndpoint) Close() {
}
type ChannelEngineConn struct {
	conn chan message
}
func NewChannelEngineConn(newConn chan message) EngineConn {
	cec := &ChannelEngineConn{
		conn: newConn,
	}
	return cec
}
func (cec *ChannelEngineConn) ReadStatement() (string, error) {
	message, ok := <-cec.conn
	if !ok {
		cec.conn = nil
		return "", io.EOF
	}
	return message.Value[0], nil
}
func (cec *ChannelEngineConn) WriteResult(lastInsertedID int64, rowsAffected int64) error {
	m := message{
		Type:  resultMessage,
		Value: []string{fmt.Sprintf("%d %d", lastInsertedID, rowsAffected)},
	}
	cec.conn <- m
	return nil
}
func (cec *ChannelEngineConn) WriteError(err error) error {
	m := message{
		Type:  errMessage,
		Value: []string{err.Error()},
	}
	cec.conn <- m
	return nil
}
func (cec *ChannelEngineConn) WriteRowHeader(header []string) error {
	m := message{
		Type:  rowHeaderMessage,
		Value: header,
	}
	cec.conn <- m
	return nil
}
func (cec *ChannelEngineConn) WriteRow(row []string) error {
	m := message{
		Type:  rowValueMessage,
		Value: row,
	}
	cec.conn <- m
	return nil
}
func (cec *ChannelEngineConn) WriteRowEnd() error {
	m := message{
		Type: rowEndMessage,
	}
	cec.conn <- m
	return nil
}