1 Star 1 Fork 0

bigbase/pg

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
hook.go 2.71 KB
一键复制 编辑 原始数据 按行查看 历史
Vladimir Mihailenco 提交于 2017-05-06 14:04 . Add context support
package pg
import (
"fmt"
"runtime"
"strings"
"time"
"github.com/go-pg/pg/orm"
)
type dummyDB struct {
orm.DB
}
var _ orm.DB = dummyDB{}
func (dummyDB) FormatQuery(dst []byte, query string, params ...interface{}) []byte {
return append(dst, query...)
}
type QueryProcessedEvent struct {
StartTime time.Time
Func string
File string
Line int
DB orm.DB
Query interface{}
Params []interface{}
Result orm.Result
Error error
}
func (ev *QueryProcessedEvent) UnformattedQuery() (string, error) {
b, err := queryString(ev.Query)
if err != nil {
return "", err
}
return string(b), nil
}
func (ev *QueryProcessedEvent) FormattedQuery() (string, error) {
b, err := appendQuery(nil, ev.DB, ev.Query, ev.Params...)
if err != nil {
return "", err
}
return string(b), nil
}
func queryString(query interface{}) ([]byte, error) {
switch query := query.(type) {
case orm.QueryAppender:
query = query.Copy()
query.Query().DB(dummyDB{})
return query.AppendQuery(nil)
case string:
return dummyDB{}.FormatQuery(nil, query), nil
default:
return nil, fmt.Errorf("pg: can't append %T", query)
}
}
type queryProcessedHook func(*QueryProcessedEvent)
// OnQueryProcessed calls the fn with QueryProcessedEvent
// when query is processed.
func (db *DB) OnQueryProcessed(fn func(*QueryProcessedEvent)) {
db.queryProcessedHooks = append(db.queryProcessedHooks, fn)
}
func (db *DB) queryProcessed(
ormDB orm.DB,
start time.Time,
query interface{},
params []interface{},
res orm.Result,
err error,
) {
if len(db.queryProcessedHooks) == 0 {
return
}
funcName, file, line := fileLine(2)
event := &QueryProcessedEvent{
StartTime: start,
Func: funcName,
File: file,
Line: line,
DB: ormDB,
Query: query,
Params: params,
Result: res,
Error: err,
}
for _, hook := range db.queryProcessedHooks {
hook(event)
}
}
const packageName = "github.com/go-pg/pg"
func fileLine(depth int) (string, string, int) {
for i := depth; ; i++ {
pc, file, line, ok := runtime.Caller(i)
if !ok {
break
}
if strings.Contains(file, packageName) {
continue
}
_, funcName := packageFuncName(pc)
return funcName, file, line
}
return "", "", 0
}
func packageFuncName(pc uintptr) (string, string) {
f := runtime.FuncForPC(pc)
if f == nil {
return "", ""
}
packageName := ""
funcName := f.Name()
if ind := strings.LastIndex(funcName, "/"); ind > 0 {
packageName += funcName[:ind+1]
funcName = funcName[ind+1:]
}
if ind := strings.Index(funcName, "."); ind > 0 {
packageName += funcName[:ind]
funcName = funcName[ind+1:]
}
return packageName, funcName
}
func copyQueryProcessedHooks(s []queryProcessedHook) []queryProcessedHook {
return s[:len(s):len(s)]
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/bigbase/pg.git
git@gitee.com:bigbase/pg.git
bigbase
pg
pg
v6.4.21

搜索帮助