forked from gitea/gitea
82 lines
1.8 KiB
Go
82 lines
1.8 KiB
Go
// Copyright 2020 The Xorm Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package contexts
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"time"
|
|
)
|
|
|
|
// ContextHook represents a hook context
|
|
type ContextHook struct {
|
|
start time.Time
|
|
Ctx context.Context
|
|
SQL string // log content or SQL
|
|
Args []interface{} // if it's a SQL, it's the arguments
|
|
Result sql.Result
|
|
ExecuteTime time.Duration
|
|
Err error // SQL executed error
|
|
}
|
|
|
|
// NewContextHook return context for hook
|
|
func NewContextHook(ctx context.Context, sql string, args []interface{}) *ContextHook {
|
|
return &ContextHook{
|
|
start: time.Now(),
|
|
Ctx: ctx,
|
|
SQL: sql,
|
|
Args: args,
|
|
}
|
|
}
|
|
|
|
// End finish the hook invokation
|
|
func (c *ContextHook) End(ctx context.Context, result sql.Result, err error) {
|
|
c.Ctx = ctx
|
|
c.Result = result
|
|
c.Err = err
|
|
c.ExecuteTime = time.Now().Sub(c.start)
|
|
}
|
|
|
|
// Hook represents a hook behaviour
|
|
type Hook interface {
|
|
BeforeProcess(c *ContextHook) (context.Context, error)
|
|
AfterProcess(c *ContextHook) error
|
|
}
|
|
|
|
// Hooks implements Hook interface but contains multiple Hook
|
|
type Hooks struct {
|
|
hooks []Hook
|
|
}
|
|
|
|
// AddHook adds a Hook
|
|
func (h *Hooks) AddHook(hooks ...Hook) {
|
|
h.hooks = append(h.hooks, hooks...)
|
|
}
|
|
|
|
// BeforeProcess invoked before execute the process
|
|
func (h *Hooks) BeforeProcess(c *ContextHook) (context.Context, error) {
|
|
ctx := c.Ctx
|
|
for _, h := range h.hooks {
|
|
var err error
|
|
ctx, err = h.BeforeProcess(c)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return ctx, nil
|
|
}
|
|
|
|
// AfterProcess invoked after exetue the process
|
|
func (h *Hooks) AfterProcess(c *ContextHook) error {
|
|
firstErr := c.Err
|
|
for _, h := range h.hooks {
|
|
err := h.AfterProcess(c)
|
|
if err != nil && firstErr == nil {
|
|
firstErr = err
|
|
}
|
|
}
|
|
return firstErr
|
|
}
|