Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pg_query integration #691

Merged
merged 20 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Polish code after modifications
  • Loading branch information
Zhaars committed Dec 6, 2023
commit 3e5b29f5c48dba739c4b051bf2c8961019f3a2fb
15 changes: 2 additions & 13 deletions cmd/acra-server/common/client_session.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ import (
"net"
"sync/atomic"

log "github.com/sirupsen/logrus"

"github.com/cossacklabs/acra/decryptor/base"
"github.com/cossacklabs/acra/logging"
"github.com/cossacklabs/acra/network"
log "github.com/sirupsen/logrus"
)

// ClientSession handles connection between database and AcraServer.
Expand All @@ -34,7 +35,6 @@ type ClientSession struct {
connectionToDb net.Conn
ctx context.Context
logger *log.Entry
statements base.PreparedStatementRegistry
protocolState interface{}
data map[string]interface{}
}
Expand Down Expand Up @@ -100,17 +100,6 @@ func (clientSession *ClientSession) DatabaseConnection() net.Conn {
return clientSession.connectionToDb
}

// PreparedStatementRegistry returns prepared statement registry of this session.
// The session does not have a registry by default, it must be set with SetPreparedStatementRegistry.
func (clientSession *ClientSession) PreparedStatementRegistry() base.PreparedStatementRegistry {
return clientSession.statements
}

// SetPreparedStatementRegistry sets prepared statement registry for this session.
func (clientSession *ClientSession) SetPreparedStatementRegistry(registry base.PreparedStatementRegistry) {
clientSession.statements = registry
}

// ProtocolState returns private protocol state of this session.
// The session does not have any state by default, it must be set with SetProtocolState.
func (clientSession *ClientSession) ProtocolState() interface{} {
Expand Down
4 changes: 0 additions & 4 deletions decryptor/base/clientSession.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ type ClientSession interface {
Context() context.Context
ClientConnection() net.Conn
DatabaseConnection() net.Conn

PreparedStatementRegistry() PreparedStatementRegistry
SetPreparedStatementRegistry(registry PreparedStatementRegistry)

ProtocolState() interface{}
SetProtocolState(state interface{})
GetData(string) (interface{}, bool)
Expand Down
8 changes: 0 additions & 8 deletions decryptor/base/clientSession_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,6 @@ func (s sessionStub) DatabaseConnection() net.Conn {
panic("implement me")
}

func (s sessionStub) PreparedStatementRegistry() PreparedStatementRegistry {
panic("implement me")
}

func (s sessionStub) SetPreparedStatementRegistry(registry PreparedStatementRegistry) {
panic("implement me")
}

func (s sessionStub) ProtocolState() interface{} {
panic("implement me")
}
Expand Down
21 changes: 13 additions & 8 deletions decryptor/base/mocks/BoundValue.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 10 additions & 32 deletions decryptor/base/mocks/ClientSession.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 5 additions & 42 deletions decryptor/base/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"fmt"
"net"

pg_query "github.com/Zhaars/pg_query_go/v4"
"github.com/sirupsen/logrus"

"github.com/cossacklabs/acra/encryptor/base/config"
Expand Down Expand Up @@ -107,6 +106,11 @@ func NewProxySetting(parser *sqlparser.Parser, tableSchema config.TableSchemaSto
}
}

// ProxyFactory create new Proxy for specific database
type ProxyFactory interface {
New(clientID []byte, clientSession ClientSession) (Proxy, error)
}

// Proxy interface to process client's requests to database and responses
type Proxy interface {
ClientIDObservable
Expand Down Expand Up @@ -142,47 +146,6 @@ func (wrapper *proxyTLSConnectionWrapper) UseConnectionClientID() bool {
return wrapper.useConnectionClientID
}

// ProxyFactory create new Proxy for specific database
type ProxyFactory interface {
New(clientID []byte, clientSession ClientSession) (Proxy, error)
}

// PreparedStatementRegistry keeps track of active prepared statements and cursors within a ClientSession.
type PreparedStatementRegistry interface {
AddStatement(statement PgPreparedStatement) error
DeleteStatement(name string) error
StatementByName(name string) (PgPreparedStatement, error)

AddCursor(cursor Cursor) error
DeleteCursor(name string) error
CursorByName(name string) (Cursor, error)
}

// PreparedStatement is a prepared statement, ready to be executed.
// It can be either a textual SQL statement from "PREPARE", or a database protocol equivalent.
type PreparedStatement interface {
Name() string
Query() sqlparser.Statement
QueryText() string
ParamsNum() int
}

// PgPreparedStatement is a prepared statement, ready to be executed.
// It can be either a textual SQL statement from "PREPARE", or a database protocol equivalent.
type PgPreparedStatement interface {
Name() string
Query() *pg_query.ParseResult
QueryText() string
ParamsNum() int
}

// Cursor is used to iterate over a prepared statement.
// It can be either a textual SQL statement from "DEFINE CURSOR", or a database protocol equivalent.
type Cursor interface {
Name() string
PreparedStatement() PgPreparedStatement
}

const (
acraDBProxyErrSide = "AcraServer-Database"
acraClientProxyErrSide = "Client-AcraServer"
Expand Down
35 changes: 22 additions & 13 deletions decryptor/mysql/prepared_statements.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,26 @@ import (
"github.com/cossacklabs/acra/utils"
)

// PreparedStatement is a prepared statement, ready to be executed.
// It can be either a textual SQL statement from "PREPARE", or a database protocol equivalent.
type PreparedStatement interface {
Name() string
Query() sqlparser.Statement
QueryText() string
ParamsNum() int
}

// ErrStatementNotFound Err returned by prepared statement registry.
var ErrStatementNotFound = errors.New("no prepared statement with given statement-id")

// PreparedStatementItem represent an item to store in PreparedStatementRegistry
type PreparedStatementItem struct {
stmt base.PreparedStatement
stmt PreparedStatement
querySelectSettings []*encryptor.QueryDataItem
}

// NewPreparedStatementItem create a new PreparedStatementItem
func NewPreparedStatementItem(stmt base.PreparedStatement, querySelectSettings []*encryptor.QueryDataItem) PreparedStatementItem {
func NewPreparedStatementItem(stmt PreparedStatement, querySelectSettings []*encryptor.QueryDataItem) PreparedStatementItem {
return PreparedStatementItem{
stmt: stmt,
querySelectSettings: querySelectSettings,
Expand All @@ -42,7 +51,7 @@ func (r *PreparedStatementItem) Name() string {
}

// Statement return PreparedStatementItem statememt
func (r *PreparedStatementItem) Statement() base.PreparedStatement {
func (r *PreparedStatementItem) Statement() PreparedStatement {
return r.stmt
}

Expand Down Expand Up @@ -86,17 +95,17 @@ func (r *PreparedStatementRegistry) AddStatement(statement PreparedStatementItem
r.statements[statement.Name()] = statement
}

// PreparedStatement is a MySQL PreparedStatement.
type PreparedStatement struct {
// MySQLPreparedStatement is a MySQL PreparedStatement.
type MySQLPreparedStatement struct {
name string
sqlString string
paramsNum int
sqlStatement sqlparser.Statement
}

// NewPreparedStatement makes a new prepared statement.
func NewPreparedStatement(statementID uint32, paramsNum uint16, sqlString string, sqlStatement sqlparser.Statement) *PreparedStatement {
return &PreparedStatement{
func NewPreparedStatement(statementID uint32, paramsNum uint16, sqlString string, sqlStatement sqlparser.Statement) *MySQLPreparedStatement {
return &MySQLPreparedStatement{
name: strconv.FormatUint(uint64(statementID), 10),
sqlString: sqlString,
sqlStatement: sqlStatement,
Expand All @@ -105,31 +114,31 @@ func NewPreparedStatement(statementID uint32, paramsNum uint16, sqlString string
}

// NewPreparedStatementWithName makes a new prepared statement with name and zero paramsNum
func NewPreparedStatementWithName(name string, sqlString string, sqlStatement sqlparser.Statement) *PreparedStatement {
return &PreparedStatement{
func NewPreparedStatementWithName(name string, sqlString string, sqlStatement sqlparser.Statement) *MySQLPreparedStatement {
return &MySQLPreparedStatement{
name: name,
sqlString: sqlString,
sqlStatement: sqlStatement,
}
}

// Name return prepared statement name
func (s *PreparedStatement) Name() string {
func (s *MySQLPreparedStatement) Name() string {
return s.name
}

// ParamsNum return number of prepared statements params
func (s *PreparedStatement) ParamsNum() int {
func (s *MySQLPreparedStatement) ParamsNum() int {
return s.paramsNum
}

// Query returns the prepared query, in its parsed form.
func (s *PreparedStatement) Query() sqlparser.Statement {
func (s *MySQLPreparedStatement) Query() sqlparser.Statement {
return s.sqlStatement
}

// QueryText returns sqlString of the prepared query, as provided by the client.
func (s *PreparedStatement) QueryText() string {
func (s *MySQLPreparedStatement) QueryText() string {
return s.sqlString
}

Expand Down
4 changes: 2 additions & 2 deletions decryptor/mysql/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,11 @@ func (stubSession) DatabaseConnection() net.Conn {
return nil
}

func (stubSession) PreparedStatementRegistry() base.PreparedStatementRegistry {
func (stubSession) PreparedStatementRegistry() *PreparedStatementRegistry {
return nil
}

func (stubSession) SetPreparedStatementRegistry(registry base.PreparedStatementRegistry) {
func (stubSession) SetPreparedStatementRegistry(registry *PreparedStatementRegistry) {
}

func (stubSession) ProtocolState() interface{} {
Expand Down
Loading