github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/sqx/daolog.go (about)

     1  package sqx
     2  
     3  import (
     4  	"database/sql"
     5  	"log"
     6  	"reflect"
     7  
     8  	"github.com/bingoohuang/gg/pkg/reflector"
     9  )
    10  
    11  // DaoLogger is the interface for dao logging.
    12  type DaoLogger interface {
    13  	// LogError logs the error
    14  	LogError(err error)
    15  	// LogStart logs the sql before the sql execution
    16  	LogStart(id, sql string, vars interface{})
    17  }
    18  
    19  var (
    20  	_daoLoggerType = reflect.TypeOf((*DaoLogger)(nil)).Elem()
    21  	_dbGetterType  = reflect.TypeOf((*DBGetter)(nil)).Elem()
    22  )
    23  
    24  // DaoLog implements the interface for dao logging with standard log.
    25  type DaoLog struct{}
    26  
    27  // LogError logs the error.
    28  func (d *DaoLog) LogError(err error) {
    29  	log.Printf("E! error occurred %v", err)
    30  }
    31  
    32  // LogStart logs the sql before the sql execution.
    33  func (d *DaoLog) LogStart(id, sql string, vars interface{}) {
    34  	log.Printf("exec %s [%s] with %v", id, sql, vars)
    35  }
    36  
    37  // getDBFn is the function type to get a sql.DBGetter.
    38  type getDBFn func() *sql.DB
    39  
    40  // GetDB returns a sql.DBGetter.
    41  func (f getDBFn) GetDB() *sql.DB { return f() }
    42  
    43  func createDBGetter(v reflect.Value, option *CreateDaoOpt) {
    44  	if option.DBGetter != nil {
    45  		return
    46  	}
    47  
    48  	if fv := findTypedField(v, _dbGetterType); fv.IsValid() {
    49  		option.DBGetter = fv.Interface().(DBGetter)
    50  		return
    51  	}
    52  
    53  	option.DBGetter = getDBFn(func() *sql.DB { return DB })
    54  }
    55  
    56  func createLogger(v reflect.Value, option *CreateDaoOpt) {
    57  	if option.Logger != nil {
    58  		return
    59  	}
    60  
    61  	if fv := findTypedField(v, _daoLoggerType); fv.IsValid() {
    62  		option.Logger = fv.Interface().(DaoLogger)
    63  		return
    64  	}
    65  
    66  	option.Logger = &DaoLog{}
    67  }
    68  
    69  func findTypedField(v reflect.Value, t reflect.Type) reflect.Value {
    70  	for i := 0; i < v.NumField(); i++ {
    71  		f := v.Type().Field(i)
    72  
    73  		if f.PkgPath != "" /* not exportable? */ {
    74  			continue
    75  		}
    76  
    77  		fv := v.Field(i)
    78  		if reflector.ImplType(f.Type, t) && !fv.IsNil() {
    79  			return fv
    80  		}
    81  	}
    82  
    83  	return reflect.Value{}
    84  }