sql.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package logger
  2. import (
  3. "database/sql/driver"
  4. "fmt"
  5. "regexp"
  6. "strconv"
  7. "strings"
  8. "time"
  9. "unicode"
  10. )
  11. func isPrintable(s []byte) bool {
  12. for _, r := range s {
  13. if !unicode.IsPrint(rune(r)) {
  14. return false
  15. }
  16. }
  17. return true
  18. }
  19. func ExplainSQL(sql string, numericPlaceholder *regexp.Regexp, escaper string, vars ...interface{}) string {
  20. for idx, v := range vars {
  21. if valuer, ok := v.(driver.Valuer); ok {
  22. v, _ = valuer.Value()
  23. }
  24. switch v := v.(type) {
  25. case bool:
  26. vars[idx] = fmt.Sprint(v)
  27. case time.Time:
  28. vars[idx] = escaper + v.Format("2006-01-02 15:04:05") + escaper
  29. case *time.Time:
  30. vars[idx] = escaper + v.Format("2006-01-02 15:04:05") + escaper
  31. case []byte:
  32. if isPrintable(v) {
  33. vars[idx] = escaper + strings.Replace(string(v), escaper, "\\"+escaper, -1) + escaper
  34. } else {
  35. vars[idx] = escaper + "<binary>" + escaper
  36. }
  37. case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
  38. vars[idx] = fmt.Sprintf("%d", v)
  39. case float64, float32:
  40. vars[idx] = fmt.Sprintf("%.6f", v)
  41. case string:
  42. vars[idx] = escaper + strings.Replace(v, escaper, "\\"+escaper, -1) + escaper
  43. default:
  44. if v == nil {
  45. vars[idx] = "NULL"
  46. } else {
  47. vars[idx] = escaper + strings.Replace(fmt.Sprint(v), escaper, "\\"+escaper, -1) + escaper
  48. }
  49. }
  50. }
  51. if numericPlaceholder == nil {
  52. for _, v := range vars {
  53. sql = strings.Replace(sql, "?", v.(string), 1)
  54. }
  55. } else {
  56. sql = numericPlaceholder.ReplaceAllString(sql, "$$$$$1")
  57. for idx, v := range vars {
  58. sql = strings.Replace(sql, "$$"+strconv.Itoa(idx), v.(string), 1)
  59. }
  60. }
  61. return sql
  62. }