You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

hook.go 1.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // Copyright 2020 The Xorm Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package contexts
  5. import (
  6. "context"
  7. "database/sql"
  8. "time"
  9. )
  10. // ContextHook represents a hook context
  11. type ContextHook struct {
  12. start time.Time
  13. Ctx context.Context
  14. SQL string // log content or SQL
  15. Args []interface{} // if it's a SQL, it's the arguments
  16. Result sql.Result
  17. ExecuteTime time.Duration
  18. Err error // SQL executed error
  19. }
  20. // NewContextHook return context for hook
  21. func NewContextHook(ctx context.Context, sql string, args []interface{}) *ContextHook {
  22. return &ContextHook{
  23. start: time.Now(),
  24. Ctx: ctx,
  25. SQL: sql,
  26. Args: args,
  27. }
  28. }
  29. func (c *ContextHook) End(ctx context.Context, result sql.Result, err error) {
  30. c.Ctx = ctx
  31. c.Result = result
  32. c.Err = err
  33. c.ExecuteTime = time.Now().Sub(c.start)
  34. }
  35. type Hook interface {
  36. BeforeProcess(c *ContextHook) (context.Context, error)
  37. AfterProcess(c *ContextHook) error
  38. }
  39. type Hooks struct {
  40. hooks []Hook
  41. }
  42. func (h *Hooks) AddHook(hooks ...Hook) {
  43. h.hooks = append(h.hooks, hooks...)
  44. }
  45. func (h *Hooks) BeforeProcess(c *ContextHook) (context.Context, error) {
  46. ctx := c.Ctx
  47. for _, h := range h.hooks {
  48. var err error
  49. ctx, err = h.BeforeProcess(c)
  50. if err != nil {
  51. return nil, err
  52. }
  53. }
  54. return ctx, nil
  55. }
  56. func (h *Hooks) AfterProcess(c *ContextHook) error {
  57. firstErr := c.Err
  58. for _, h := range h.hooks {
  59. err := h.AfterProcess(c)
  60. if err != nil && firstErr == nil {
  61. firstErr = err
  62. }
  63. }
  64. return firstErr
  65. }