Documentation
¶
Overview ¶
Package base provides common infrastructure for protocol proxies
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DatabaseProxyConfig ¶ added in v1.4.0
type DatabaseProxyConfig struct {
DatabaseName string // Configurable database name
}
DatabaseProxyConfig holds database name configuration for any database proxy This provides a common base for all database types (MySQL, PostgreSQL, MongoDB, etc.)
func NewDatabaseProxyConfig ¶ added in v1.4.0
func NewDatabaseProxyConfig(databaseName string) *DatabaseProxyConfig
NewDatabaseProxyConfig creates a new config with the given database name If databaseName is empty, it uses a sensible default
func (*DatabaseProxyConfig) GetDatabaseName ¶ added in v1.4.0
func (c *DatabaseProxyConfig) GetDatabaseName() string
GetDatabaseName returns the current database name
func (*DatabaseProxyConfig) SetDatabaseName ¶ added in v1.4.0
func (c *DatabaseProxyConfig) SetDatabaseName(name string)
SetDatabaseName sets the database name
type ProtocolHandler ¶
type ProtocolHandler interface {
// Name returns the name of this protocol handler (e.g., "mysql", "postgresql")
Name() string
// HandleConnection handles the main proxying loop for a connection pair
// This is the primary method that implementations should override
HandleConnection(clientConn, upstreamConn net.Conn)
// HandleClientStartup performs the initial handshake with a client connection
// Returns connection parameters and any error
HandleClientStartup(clientConn net.Conn) (map[string]string, error)
// HandleUpstreamStartup performs the initial handshake with the upstream server
// Returns any error
HandleUpstreamStartup(upstreamConn net.Conn) error
// ReadClientMessage reads a message from the client
// Returns nil when connection is closed
ReadClientMessage(clientConn net.Conn) (*Message, error)
// ReadUpstreamMessage reads a message from the upstream server
ReadUpstreamMessage(upstreamConn net.Conn) (*Message, error)
// WriteClientMessage writes a message to the client
WriteClientMessage(clientConn net.Conn, msg *Message) error
// WriteUpstreamMessage writes a message to the upstream server
WriteUpstreamMessage(upstreamConn net.Conn, msg *Message) error
// ExtractQuery extracts SQL and metadata from a message
// Returns nil if message is not a query
ExtractQuery(msg *Message) *QueryInfo
// IsExtendedProtocolMessage returns true if message is part of extended query protocol
// (e.g., Parse, Bind, Execute, Describe in PostgreSQL)
IsExtendedProtocolMessage(msg *Message) bool
// HandleExtendedProtocol handles extended protocol message
// Returns true if message was handled, false to forward to upstream
HandleExtendedProtocol(msg *Message, upstreamConn, clientConn net.Conn) (bool, error)
// CreateMockQueryResponse creates a mock response for a simple query
CreateMockQueryResponse(query *QueryInfo, columns []string, rows []map[string]interface{}) ([]*Message, error)
// CreateMockExtendedResponse creates mock responses for extended protocol
// (e.g., ParseComplete, BindComplete, RowDescription, DataRow, CommandComplete)
CreateMockExtendedResponse(query *QueryInfo, columns []string, rows []map[string]interface{}) ([]*Message, error)
// CreateEmptyResultSet creates an empty result set response
CreateEmptyResultSet(columns []string) ([]*Message, error)
// CreateOKResponse creates a success response for write operations
CreateOKResponse(query *QueryInfo) ([]*Message, error)
// CreateErrorResponse creates an error response message
CreateErrorResponse(errorMessage string) ([]*Message, error)
// IsWhitelisted checks if a query should bypass mocking
IsWhitelisted(query *QueryInfo) bool
}
ProtocolHandler defines the interface for database protocol handlers Implementations must handle the wire protocol specifics for each database type
type Proxy ¶ added in v1.4.0
type Proxy struct {
Registry *registry.MockRegistry
IsWhitelisted func(query string) bool
ExtractTable func(query string) string
}
Proxy manages database proxy connections using the MySQL pattern: 1. Connect to upstream FIRST 2. Start goroutine piping upstream->client transparently (includes startup) 3. In main goroutine, read client->upstream with selective interception
func NewProxy ¶ added in v1.4.0
func NewProxy( registry *registry.MockRegistry, isWhitelisted func(query string) bool, extractTable func(query string) string, ) *Proxy
NewProxy creates a new proxy with the given configuration
func (*Proxy) HandleConnection ¶ added in v1.4.0
func (p *Proxy) HandleConnection( clientConn net.Conn, upstreamAddr string, readQuery func([]byte) string, interceptQuery func(string, net.Conn) (bool, error), ) error
HandleConnection manages a single client connection following the MySQL proxy pattern. This is the CORE method that fixes the PostgreSQL startup issue. Pattern:
- Connect to upstream FIRST
- Start goroutine: io.Copy(upstream, client) - transparent pipe
- Main goroutine: read client, decide intercept vs forward
type ProxyConfig ¶
type ProxyConfig struct {
ListenAddr string
UpstreamAddr string
Registry *registry.MockRegistry
Handler ProtocolHandler
}
ProxyConfig holds configuration for a protocol proxy
type ProxyServer ¶
type ProxyServer struct {
// contains filtered or unexported fields
}
ProxyServer is a generic protocol proxy server
func NewProxyServer ¶
func NewProxyServer(config ProxyConfig) *ProxyServer
NewProxyServer creates a new proxy server