github.com/lovung/GoCleanArchitecture@v0.0.0-20210302152432-50d91fd29f9f/app/internal/pkg/gormutil/callbacks.go (about)

     1  package gormutil
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/lovung/GoCleanArchitecture/pkg/jwtutil"
     7  	"gorm.io/gorm"
     8  )
     9  
    10  const (
    11  	maxPageSize = 1000
    12  )
    13  
    14  // Paging defines paging struct
    15  type Paging struct{ Size, Number uint64 }
    16  
    17  // WithID where id = <input value>
    18  func WithID(id interface{}) func(d *gorm.DB) *gorm.DB {
    19  	return func(d *gorm.DB) *gorm.DB {
    20  		return d.Where("id = (?)", id)
    21  	}
    22  }
    23  
    24  // WithDeletedAtNull where code = <input value>
    25  func WithDeletedAtNull(table string) func(d *gorm.DB) *gorm.DB {
    26  	return func(d *gorm.DB) *gorm.DB {
    27  		return d.Where(table + ".deleted_at IS NULL")
    28  	}
    29  }
    30  
    31  // WithUserID where office_id = office_id from context
    32  func WithUserID() func(d *gorm.DB) *gorm.DB {
    33  	return func(d *gorm.DB) *gorm.DB {
    34  		claim := d.Statement.Context.Value(jwtutil.JWTClaimsKey)
    35  		table := d.Statement.Table
    36  		if claim != nil {
    37  			if claimInfo, ok := claim.(jwtutil.JWTClaims); ok {
    38  				if table != "" {
    39  					return d.Where("`"+table+"`.`user_id` = (?)", claimInfo.UserID)
    40  				}
    41  				return d.Where("`user_id` = (?)", claimInfo.UserID)
    42  			}
    43  		}
    44  		return d
    45  	}
    46  }
    47  
    48  // UpdateWithClaimInfo add update office_id and updated_by from context
    49  func UpdateWithClaimInfo(d *gorm.DB, data map[string]interface{}) map[string]interface{} {
    50  	claim := d.Statement.Context.Value(jwtutil.JWTClaimsKey)
    51  	if claim != nil {
    52  		if claimInfo, ok := claim.(jwtutil.JWTClaims); ok {
    53  			if _, ok := data["updated_by"]; ok {
    54  				data["updated_by"] = claimInfo.UserID
    55  			}
    56  		}
    57  	}
    58  	return data
    59  }
    60  
    61  // DeletedByFromClaim for the hook after deleting record.
    62  func DeletedByFromClaim(d *gorm.DB) (map[string]interface{}, bool) {
    63  	claim := d.Statement.Context.Value(jwtutil.JWTClaimsKey)
    64  
    65  	clause := make(map[string]interface{}, 1)
    66  	if claimInfo, ok := claim.(jwtutil.JWTClaims); ok {
    67  		clause["deleted_by"] = claimInfo.UserID
    68  		return clause, true
    69  	}
    70  
    71  	// This situation is not expected to happen ecause AuthMiddleware ensures JWTClaims exists
    72  	return clause, false
    73  }
    74  
    75  // SoftDeleteClauseFromClaim for Bulk SoftDelete
    76  func SoftDeleteClauseFromClaim(d *gorm.DB, now time.Time) (map[string]interface{}, bool) {
    77  	claim := d.Statement.Context.Value(jwtutil.JWTClaimsKey)
    78  
    79  	clause := make(map[string]interface{}, 2)
    80  	if claimInfo, ok := claim.(jwtutil.JWTClaims); ok {
    81  		clause["deleted_by"] = claimInfo.UserID
    82  		clause["deleted_at"] = now
    83  		return clause, true
    84  	}
    85  
    86  	// This situation is not expected to happen ecause AuthMiddleware ensures JWTClaims exists
    87  	return clause, false
    88  }
    89  
    90  // SoftDeleteClauseFromClaimWithDefaultTime for Bulk SoftDelete with Now
    91  func SoftDeleteClauseFromClaimWithDefaultTime(d *gorm.DB) (map[string]interface{}, bool) {
    92  	now := time.Now()
    93  	return SoftDeleteClauseFromClaim(d, now)
    94  }
    95  
    96  // Paginate page with limit and offset
    97  func Paginate(paging Paging) func(db *gorm.DB) *gorm.DB {
    98  	return func(db *gorm.DB) *gorm.DB {
    99  		switch {
   100  		case paging.Size == 0: // used for current have no paging, will remove in the future
   101  			paging.Size = maxPageSize
   102  		case paging.Size > maxPageSize:
   103  			paging.Size = maxPageSize
   104  		}
   105  		if paging.Number == 0 {
   106  			paging.Number = 1
   107  		}
   108  
   109  		offset := (paging.Number - 1) * paging.Size
   110  		return db.Offset(int(offset)).Limit(int(paging.Size))
   111  	}
   112  }