package db import ( "fmt" "reflect" "github.com/iancoleman/strcase" "gorm.io/gorm" "reichard.io/imagini/graph/model" ) // Generic function used to generate filters for the DB func (dbm *DBManager) generateFilter(tx *gorm.DB, filter interface{}) *gorm.DB { ptr := reflect.ValueOf(filter) v := reflect.Indirect(ptr) if v == reflect.ValueOf(nil) { return tx } for i := 0; i < v.NumField(); i++ { fieldName := strcase.ToSnake(v.Type().Field(i).Name) fieldVal := v.Field(i) if fieldVal.IsNil() { continue } switch valType := fieldVal.Type(); valType { case reflect.TypeOf(&model.StringFilter{}): tx = generateStringFilter(tx, fieldName, fieldVal.Interface().(*model.StringFilter)) case reflect.TypeOf(&model.BooleanFilter{}): tx = generateBooleanFilter(tx, fieldName, fieldVal.Interface().(*model.BooleanFilter)) case reflect.TypeOf(&model.FloatFilter{}): tx = generateFloatFilter(tx, fieldName, fieldVal.Interface().(*model.FloatFilter)) case reflect.TypeOf(&model.IntFilter{}): tx = generateIntFilter(tx, fieldName, fieldVal.Interface().(*model.IntFilter)) case reflect.TypeOf(&model.IDFilter{}): tx = generateIDFilter(tx, fieldName, fieldVal.Interface().(*model.IDFilter)) case reflect.TypeOf(&model.TimeFilter{}): tx = generateTimeFilter(tx, fieldName, fieldVal.Interface().(*model.TimeFilter)) case reflect.TypeOf(&model.RoleFilter{}): tx = generateRoleFilter(tx, fieldName, fieldVal.Interface().(*model.RoleFilter)) case reflect.TypeOf(&model.DeviceTypeFilter{}): tx = generateDeviceTypeFilter(tx, fieldName, fieldVal.Interface().(*model.DeviceTypeFilter)) case reflect.TypeOf(&model.AuthTypeFilter{}): tx = generateAuthTypeFilter(tx, fieldName, fieldVal.Interface().(*model.AuthTypeFilter)) } } return tx } func generateStringFilter(tx *gorm.DB, fieldName string, filter *model.StringFilter) *gorm.DB { if filter.EqualTo != nil { tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo) } if filter.NotEqualTo != nil { tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo) } if filter.StartsWith != nil { tx = tx.Where(fmt.Sprintf("%s LIKE ?", fieldName), fmt.Sprintf("%s%%", *filter.StartsWith)) } if filter.NotStartsWith != nil { tx = tx.Where(fmt.Sprintf("%s NOT LIKE ?", fieldName), fmt.Sprintf("%s%%", *filter.NotStartsWith)) } if filter.EndsWith != nil { tx = tx.Where(fmt.Sprintf("%s LIKE ?", fieldName), fmt.Sprintf("%%%s", *filter.EndsWith)) } if filter.NotEndsWith != nil { tx = tx.Where(fmt.Sprintf("%s NOT LIKE ?", fieldName), fmt.Sprintf("%%%s", *filter.NotEndsWith)) } if filter.Contains != nil { tx = tx.Where(fmt.Sprintf("%s LIKE ?", fieldName), fmt.Sprintf("%%%s%%", *filter.Contains)) } if filter.NotContains != nil { tx = tx.Where(fmt.Sprintf("%s NOT LIKE ?", fieldName), fmt.Sprintf("%%%s%%", *filter.NotContains)) } return tx } func generateBooleanFilter(tx *gorm.DB, fieldName string, filter *model.BooleanFilter) *gorm.DB { if filter.EqualTo != nil { tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo) } if filter.NotEqualTo != nil { tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo) } return tx } func generateFloatFilter(tx *gorm.DB, fieldName string, filter *model.FloatFilter) *gorm.DB { if filter.EqualTo != nil { tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo) } if filter.NotEqualTo != nil { tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo) } if filter.GreaterThan != nil { tx = tx.Where(fmt.Sprintf("%s > ?", fieldName), *filter.GreaterThan) } if filter.GreaterThanOrEqualTo != nil { tx = tx.Where(fmt.Sprintf("%s >= ?", fieldName), *filter.GreaterThanOrEqualTo) } if filter.LessThan != nil { tx = tx.Where(fmt.Sprintf("%s < ?", fieldName), *filter.LessThan) } if filter.LessThanOrEqualTo != nil { tx = tx.Where(fmt.Sprintf("%s <= ?", fieldName), *filter.LessThanOrEqualTo) } return tx } func generateIntFilter(tx *gorm.DB, fieldName string, filter *model.IntFilter) *gorm.DB { if filter.EqualTo != nil { tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo) } if filter.NotEqualTo != nil { tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo) } if filter.GreaterThan != nil { tx = tx.Where(fmt.Sprintf("%s > ?", fieldName), *filter.GreaterThan) } if filter.GreaterThanOrEqualTo != nil { tx = tx.Where(fmt.Sprintf("%s >= ?", fieldName), *filter.GreaterThanOrEqualTo) } if filter.LessThan != nil { tx = tx.Where(fmt.Sprintf("%s < ?", fieldName), *filter.LessThan) } if filter.LessThanOrEqualTo != nil { tx = tx.Where(fmt.Sprintf("%s <= ?", fieldName), *filter.LessThanOrEqualTo) } return tx } func generateIDFilter(tx *gorm.DB, fieldName string, filter *model.IDFilter) *gorm.DB { if filter.EqualTo != nil { tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo) } if filter.NotEqualTo != nil { tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo) } return tx } func generateTimeFilter(tx *gorm.DB, fieldName string, filter *model.TimeFilter) *gorm.DB { if filter.EqualTo != nil { tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo) } if filter.NotEqualTo != nil { tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo) } if filter.GreaterThan != nil { tx = tx.Where(fmt.Sprintf("%s > ?", fieldName), *filter.GreaterThan) } if filter.GreaterThanOrEqualTo != nil { tx = tx.Where(fmt.Sprintf("%s >= ?", fieldName), *filter.GreaterThanOrEqualTo) } if filter.LessThan != nil { tx = tx.Where(fmt.Sprintf("%s < ?", fieldName), *filter.LessThan) } if filter.LessThanOrEqualTo != nil { tx = tx.Where(fmt.Sprintf("%s <= ?", fieldName), *filter.LessThanOrEqualTo) } return tx } func generateRoleFilter(tx *gorm.DB, fieldName string, filter *model.RoleFilter) *gorm.DB { if filter.EqualTo != nil { tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo) } if filter.NotEqualTo != nil { tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo) } return tx } func generateDeviceTypeFilter(tx *gorm.DB, fieldName string, filter *model.DeviceTypeFilter) *gorm.DB { if filter.EqualTo != nil { tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo) } if filter.NotEqualTo != nil { tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo) } return tx } func generateAuthTypeFilter(tx *gorm.DB, fieldName string, filter *model.AuthTypeFilter) *gorm.DB { if filter.EqualTo != nil { tx = tx.Where(fmt.Sprintf("%s == ?", fieldName), *filter.EqualTo) } if filter.NotEqualTo != nil { tx = tx.Where(fmt.Sprintf("%s != ?", fieldName), *filter.NotEqualTo) } return tx }