mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 01:02:25 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			110 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package bun
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"database/sql"
 | |
| 	"strings"
 | |
| 	"sync/atomic"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/uptrace/bun/schema"
 | |
| )
 | |
| 
 | |
| type QueryEvent struct {
 | |
| 	DB *DB
 | |
| 
 | |
| 	QueryAppender schema.QueryAppender // Deprecated: use IQuery instead
 | |
| 	IQuery        Query
 | |
| 	Query         string
 | |
| 	QueryArgs     []interface{}
 | |
| 	Model         Model
 | |
| 
 | |
| 	StartTime time.Time
 | |
| 	Result    sql.Result
 | |
| 	Err       error
 | |
| 
 | |
| 	Stash map[interface{}]interface{}
 | |
| }
 | |
| 
 | |
| func (e *QueryEvent) Operation() string {
 | |
| 	if e.IQuery != nil {
 | |
| 		return e.IQuery.Operation()
 | |
| 	}
 | |
| 	return queryOperation(e.Query)
 | |
| }
 | |
| 
 | |
| func queryOperation(query string) string {
 | |
| 	if idx := strings.IndexByte(query, ' '); idx > 0 {
 | |
| 		query = query[:idx]
 | |
| 	}
 | |
| 	if len(query) > 16 {
 | |
| 		query = query[:16]
 | |
| 	}
 | |
| 	return query
 | |
| }
 | |
| 
 | |
| type QueryHook interface {
 | |
| 	BeforeQuery(context.Context, *QueryEvent) context.Context
 | |
| 	AfterQuery(context.Context, *QueryEvent)
 | |
| }
 | |
| 
 | |
| func (db *DB) beforeQuery(
 | |
| 	ctx context.Context,
 | |
| 	iquery Query,
 | |
| 	query string,
 | |
| 	queryArgs []interface{},
 | |
| 	model Model,
 | |
| ) (context.Context, *QueryEvent) {
 | |
| 	atomic.AddUint32(&db.stats.Queries, 1)
 | |
| 
 | |
| 	if len(db.queryHooks) == 0 {
 | |
| 		return ctx, nil
 | |
| 	}
 | |
| 
 | |
| 	event := &QueryEvent{
 | |
| 		DB: db,
 | |
| 
 | |
| 		Model:         model,
 | |
| 		QueryAppender: iquery,
 | |
| 		IQuery:        iquery,
 | |
| 		Query:         query,
 | |
| 		QueryArgs:     queryArgs,
 | |
| 
 | |
| 		StartTime: time.Now(),
 | |
| 	}
 | |
| 
 | |
| 	for _, hook := range db.queryHooks {
 | |
| 		ctx = hook.BeforeQuery(ctx, event)
 | |
| 	}
 | |
| 
 | |
| 	return ctx, event
 | |
| }
 | |
| 
 | |
| func (db *DB) afterQuery(
 | |
| 	ctx context.Context,
 | |
| 	event *QueryEvent,
 | |
| 	res sql.Result,
 | |
| 	err error,
 | |
| ) {
 | |
| 	switch err {
 | |
| 	case nil, sql.ErrNoRows:
 | |
| 		// nothing
 | |
| 	default:
 | |
| 		atomic.AddUint32(&db.stats.Errors, 1)
 | |
| 	}
 | |
| 
 | |
| 	if event == nil {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	event.Result = res
 | |
| 	event.Err = err
 | |
| 
 | |
| 	db.afterQueryFromIndex(ctx, event, len(db.queryHooks)-1)
 | |
| }
 | |
| 
 | |
| func (db *DB) afterQueryFromIndex(ctx context.Context, event *QueryEvent, hookIndex int) {
 | |
| 	for ; hookIndex >= 0; hookIndex-- {
 | |
| 		db.queryHooks[hookIndex].AfterQuery(ctx, event)
 | |
| 	}
 | |
| }
 |