Skip to content

Instantly share code, notes, and snippets.

@Songmu
Created February 2, 2021 17:16
Show Gist options
  • Save Songmu/87bcbb69a63012b1f017fb008c708afc to your computer and use it in GitHub Desktop.
Save Songmu/87bcbb69a63012b1f017fb008c708afc to your computer and use it in GitHub Desktop.
embed comment into sql
func findCaller() (*runtime.Frame, string) {
// skip starts 6. 0: Callers, 1: findCaller, 2: sqlComment, 3: hooks, 4: proxy-funcs, 5: database/sql, and equals or greater than 6: user-funcs
skip := 6
for {
var rpc [8]uintptr
var i int
n := runtime.Callers(skip, rpc[:])
frames := runtime.CallersFrames(rpc[:])
for i = 0; ; i++ {
frame, more := frames.Next()
if !more {
break
}
name := frame.Function
if name == "" || strings.HasPrefix(name, "runtime.") {
continue
}
// http://stackoverflow.com/questions/25262754/how-to-get-name-of-current-package-in-go
dotIdx := 0
for j := len(name) - 1; j >= 0; j-- {
if name[j] == '.' {
dotIdx = j
} else if name[j] == '/' {
break
}
}
packageName := name[:dotIdx]
if !skipForSQLComment(frame, packageName) {
return &frame, packageName
}
}
if n < len(rpc) {
break
}
skip += i
}
return nil, ""
}
sql.Register("sql-proxy", proxy.NewProxy(&mysql.MySQLDriver{}, &proxy.HooksContext{
PrePrepare: func(ctx context.Context, stmt *proxy.Stmt) (interface{}, error) {
sqlComment(stmt)
return nil, nil
},
PreExec: func(ctx context.Context, stmt *proxy.Stmt, _ []driver.NamedValue) (interface{}, error) {
if stmt.Stmt == nil {
sqlComment(stmt)
}
return nil, nil
},
PreQuery: func(ctx context.Context, stmt *proxy.Stmt, _ []driver.NamedValue) (interface{}, error) {
if stmt.Stmt == nil {
sqlComment(stmt)
}
return nil, nil
},
}
func sqlComment(stmt *proxy.Stmt) {
f, pkgName := findCaller()
if f != nil {
fname := filepath.Base(f.File)
relPath := strings.TrimPrefix(pkgName, "github.com/owner/myprojrepo/")
comment := fmt.Sprintf("%s/%s:%d", relPath, fname, f.Line)
comment = strings.ReplaceAll(comment, "*", "")
stmt.QueryString = fmt.Sprintf("/* %s */\n%s", comment, stmt.QueryString)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment