type ocDriver struct {
parent driver .Driver
connector driver .Connector
options TraceOptions
}
func wrapDriver (d driver .Driver , o TraceOptions ) driver .Driver {
if _ , ok := d .(driver .DriverContext ); ok {
return ocDriver {parent : d , options : o }
}
return struct { driver .Driver }{ocDriver {parent : d , options : o }}
}
func wrapConn (parent driver .Conn , options TraceOptions ) driver .Conn {
var (
n , hasNameValueChecker = parent .(driver .NamedValueChecker )
s , hasSessionResetter = parent .(driver .SessionResetter )
)
c := &ocConn {parent : parent , options : options }
switch {
case !hasNameValueChecker && !hasSessionResetter :
return c
case hasNameValueChecker && !hasSessionResetter :
return struct {
conn
driver .NamedValueChecker
}{c , n }
case !hasNameValueChecker && hasSessionResetter :
return struct {
conn
driver .SessionResetter
}{c , s }
case hasNameValueChecker && hasSessionResetter :
return struct {
conn
driver .NamedValueChecker
driver .SessionResetter
}{c , n , s }
}
panic ("unreachable" )
}
func wrapStmt (stmt driver .Stmt , query string , options TraceOptions ) driver .Stmt {
var (
_ , hasExeCtx = stmt .(driver .StmtExecContext )
_ , hasQryCtx = stmt .(driver .StmtQueryContext )
c , hasColConv = stmt .(driver .ColumnConverter )
n , hasNamValChk = stmt .(driver .NamedValueChecker )
)
s := ocStmt {parent : stmt , query : query , options : options }
switch {
case !hasExeCtx && !hasQryCtx && !hasColConv && !hasNamValChk :
return struct {
driver .Stmt
}{s }
case !hasExeCtx && hasQryCtx && !hasColConv && !hasNamValChk :
return struct {
driver .Stmt
driver .StmtQueryContext
}{s , s }
case hasExeCtx && !hasQryCtx && !hasColConv && !hasNamValChk :
return struct {
driver .Stmt
driver .StmtExecContext
}{s , s }
case hasExeCtx && hasQryCtx && !hasColConv && !hasNamValChk :
return struct {
driver .Stmt
driver .StmtExecContext
driver .StmtQueryContext
}{s , s , s }
case !hasExeCtx && !hasQryCtx && hasColConv && !hasNamValChk :
return struct {
driver .Stmt
driver .ColumnConverter
}{s , c }
case !hasExeCtx && hasQryCtx && hasColConv && !hasNamValChk :
return struct {
driver .Stmt
driver .StmtQueryContext
driver .ColumnConverter
}{s , s , c }
case hasExeCtx && !hasQryCtx && hasColConv && !hasNamValChk :
return struct {
driver .Stmt
driver .StmtExecContext
driver .ColumnConverter
}{s , s , c }
case hasExeCtx && hasQryCtx && hasColConv && !hasNamValChk :
return struct {
driver .Stmt
driver .StmtExecContext
driver .StmtQueryContext
driver .ColumnConverter
}{s , s , s , c }
case !hasExeCtx && !hasQryCtx && !hasColConv && hasNamValChk :
return struct {
driver .Stmt
driver .NamedValueChecker
}{s , n }
case !hasExeCtx && hasQryCtx && !hasColConv && hasNamValChk :
return struct {
driver .Stmt
driver .StmtQueryContext
driver .NamedValueChecker
}{s , s , n }
case hasExeCtx && !hasQryCtx && !hasColConv && hasNamValChk :
return struct {
driver .Stmt
driver .StmtExecContext
driver .NamedValueChecker
}{s , s , n }
case hasExeCtx && hasQryCtx && !hasColConv && hasNamValChk :
return struct {
driver .Stmt
driver .StmtExecContext
driver .StmtQueryContext
driver .NamedValueChecker
}{s , s , s , n }
case !hasExeCtx && !hasQryCtx && hasColConv && hasNamValChk :
return struct {
driver .Stmt
driver .ColumnConverter
driver .NamedValueChecker
}{s , c , n }
case !hasExeCtx && hasQryCtx && hasColConv && hasNamValChk :
return struct {
driver .Stmt
driver .StmtQueryContext
driver .ColumnConverter
driver .NamedValueChecker
}{s , s , c , n }
case hasExeCtx && !hasQryCtx && hasColConv && hasNamValChk :
return struct {
driver .Stmt
driver .StmtExecContext
driver .ColumnConverter
driver .NamedValueChecker
}{s , s , c , n }
case hasExeCtx && hasQryCtx && hasColConv && hasNamValChk :
return struct {
driver .Stmt
driver .StmtExecContext
driver .StmtQueryContext
driver .ColumnConverter
driver .NamedValueChecker
}{s , s , s , c , n }
}
panic ("unreachable" )
}
func (d ocDriver ) OpenConnector (name string ) (driver .Connector , error ) {
var err error
d .connector , err = d .parent .(driver .DriverContext ).OpenConnector (name )
if err != nil {
return nil , err
}
return d , err
}
func (d ocDriver ) Connect (ctx context .Context ) (driver .Conn , error ) {
c , err := d .connector .Connect (ctx )
if err != nil {
return nil , err
}
return &ocConn {parent : c , options : d .options }, nil
}
func (d ocDriver ) Driver () driver .Driver {
return d