Exercise 1
This commit is contained in:
255
ex1/proto/queries.go
Normal file
255
ex1/proto/queries.go
Normal file
@@ -0,0 +1,255 @@
|
||||
package proto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func GetMax[T float64 | float32 | int | uint | int8 | uint8 | int16 | uint16 | int32 | uint32 | int64 | uint64](a, b T) T {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func GetMin[T float64 | float32 | int | uint | int8 | uint8 | int16 | uint16 | int32 | uint32 | int64 | uint64](a, b T) T {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
|
||||
type EmployeeField string
|
||||
|
||||
const (
|
||||
FieldEmpID EmployeeField = "EmpId"
|
||||
FieldNamePrefix = "NamePrefix"
|
||||
FieldFirstName = "FirstName"
|
||||
FieldMiddleInitial = "MiddleInitial"
|
||||
FieldLastName = "LastName"
|
||||
FieldGender = "Gender"
|
||||
FieldEmail = "Email"
|
||||
FieldFathersName = "FathersName"
|
||||
FieldMothersName = "MothersName"
|
||||
FieldMothersMaidenName = "MothersMaidenName"
|
||||
FieldBirthdate = "Birthdate"
|
||||
FieldBirthTime = "BirthTime"
|
||||
FieldWeightKg = "WeightKg"
|
||||
FieldJoiningDate = "JoiningDate"
|
||||
FieldJoiningQuarter = "JoiningQuarter"
|
||||
FieldJoiningHalf = "JoiningHalf"
|
||||
FieldJoiningYear = "JoiningYear"
|
||||
FieldJoiningMonth = "JoiningMonth"
|
||||
FieldJoiningMonthName = "JoiningMonthName"
|
||||
FieldJoiningMonthNameShort = "JoiningMonthNameShort"
|
||||
FieldJoiningMonthDay = "JoiningMonthDay"
|
||||
FieldJoiningWeekDay = "JoiningWeekDay"
|
||||
FieldJoiningWeekDayShort = "JoiningWeekDayShort"
|
||||
FieldYearsOfService = "YearsOfService"
|
||||
FieldSalary = "Salary"
|
||||
FieldLatestHikePercentage = "LatestHikePercentage"
|
||||
FieldSsn = "Ssn"
|
||||
FieldPhoneNumber = "PhoneNumber"
|
||||
FieldPlaceName = "PlaceName"
|
||||
FieldCounty = "County"
|
||||
FieldCity = "City"
|
||||
FieldState = "State"
|
||||
FieldZip = "Zip"
|
||||
FieldRegion = "Region"
|
||||
FieldUsername = "Username"
|
||||
FieldPassword = "Password"
|
||||
)
|
||||
|
||||
func SnakeCaseToPascalCase(s string) string {
|
||||
words := strings.Split(s, "_")
|
||||
for i, word := range words {
|
||||
words[i] = strings.ToUpper(word[0:1]) + strings.ToLower(word[1:])
|
||||
}
|
||||
return strings.Join(words, "")
|
||||
}
|
||||
|
||||
|
||||
func (e *Employee) Copy() Employee {
|
||||
return Employee{
|
||||
EmpId: e.GetEmpId(),
|
||||
NamePrefix: e.GetNamePrefix(),
|
||||
FirstName: e.GetFirstName(),
|
||||
MiddleInitial: e.GetMiddleInitial(),
|
||||
LastName: e.GetLastName(),
|
||||
Gender: e.GetGender(),
|
||||
Email: e.GetEmail(),
|
||||
FathersName: e.GetFathersName(),
|
||||
MothersName: e.GetMothersName(),
|
||||
MothersMaidenName: e.GetMothersMaidenName(),
|
||||
Birthdate: e.GetBirthdate(),
|
||||
BirthTime: e.GetBirthTime(),
|
||||
WeightKg: e.GetWeightKg(),
|
||||
JoiningDate: e.GetJoiningDate(),
|
||||
JoiningQuarter: e.GetJoiningQuarter(),
|
||||
JoiningHalf: e.GetJoiningHalf(),
|
||||
JoiningYear: e.GetJoiningYear(),
|
||||
JoiningMonth: e.GetJoiningMonth(),
|
||||
JoiningMonthName: e.GetJoiningMonthName(),
|
||||
JoiningMonthNameShort: e.GetJoiningMonthNameShort(),
|
||||
JoiningMonthDay: e.GetJoiningMonthDay(),
|
||||
JoiningWeekDay: e.GetJoiningWeekDay(),
|
||||
JoiningWeekDayShort: e.GetJoiningWeekDayShort(),
|
||||
YearsOfService: e.GetYearsOfService(),
|
||||
Salary: e.GetSalary(),
|
||||
LatestHikePercentage: e.GetLatestHikePercentage(),
|
||||
Ssn: e.GetSsn(),
|
||||
PhoneNumber: e.GetPhoneNumber(),
|
||||
PlaceName: e.GetPlaceName(),
|
||||
County: e.GetCounty(),
|
||||
City: e.GetCity(),
|
||||
State: e.GetState(),
|
||||
Zip: e.GetZip(),
|
||||
Region: e.GetRegion(),
|
||||
Username: e.GetUsername(),
|
||||
Password: e.GetPassword(),
|
||||
}
|
||||
}
|
||||
|
||||
func (el *EmployeeList) QueryEmployeesByColumn(column EmployeeField, query string) ([]*Employee, error) {
|
||||
employees := make([]*Employee, 0)
|
||||
|
||||
for _, employee := range el.GetEmployees() {
|
||||
value := reflect.ValueOf(employee).Elem().FieldByName(string(column))
|
||||
if fmt.Sprintf("%v", value) == query {
|
||||
employees = append(employees, employee)
|
||||
}
|
||||
}
|
||||
|
||||
return employees, nil
|
||||
}
|
||||
|
||||
type Groups map[string][]*Employee
|
||||
|
||||
func (el *EmployeeList) GroupByColumn(column EmployeeField) Groups {
|
||||
|
||||
groups := make(map[string][]*Employee)
|
||||
for _, employee := range el.GetEmployees() {
|
||||
value := reflect.ValueOf(employee).Elem().FieldByName(string(column))
|
||||
formattedValue := fmt.Sprintf("%v", value)
|
||||
groups[formattedValue] = append(groups[formattedValue], employee)
|
||||
}
|
||||
|
||||
return groups
|
||||
}
|
||||
|
||||
type FilterFunction func(*Employee) bool
|
||||
|
||||
func (grps Groups) HavingByColumn(cb FilterFunction) Groups {
|
||||
|
||||
newGrps := make(map[string][]*Employee)
|
||||
|
||||
for groupName, group := range grps {
|
||||
for _, employee := range group {
|
||||
if cb(employee) {
|
||||
newGrps[groupName] = append(newGrps[groupName], employee)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newGrps
|
||||
}
|
||||
|
||||
func ForEachGroup[T any](grps Groups, cb func(ep EmployeePList) T) map[string]T {
|
||||
g := make(map[string]T)
|
||||
for groupName, group := range grps {
|
||||
g[groupName] = cb(group)
|
||||
}
|
||||
|
||||
return g
|
||||
}
|
||||
|
||||
func AggregateByColumn[T any](el *EmployeeList, column EmployeeField, cb func(ep EmployeePList) T) map[string]T {
|
||||
|
||||
grps := el.GroupByColumn(column)
|
||||
res := ForEachGroup(grps, cb)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
type EmployeePList []*Employee
|
||||
|
||||
func Sum(ep EmployeePList, column EmployeeField) float64 {
|
||||
sum := 0.0
|
||||
|
||||
_, fieldFound := reflect.TypeOf(Employee{}).FieldByName(string(column))
|
||||
if !fieldFound {
|
||||
return sum
|
||||
}
|
||||
|
||||
for _, employee := range ep {
|
||||
value := reflect.ValueOf(employee).Elem().FieldByName(string(column))
|
||||
switch value.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
sum += float64(value.Int())
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
sum += float64(value.Uint())
|
||||
case reflect.Float64, reflect.Float32:
|
||||
sum += value.Float()
|
||||
default:
|
||||
return sum
|
||||
}
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func Average(ep EmployeePList, column EmployeeField) float64 {
|
||||
return Sum(ep, column) / float64(len(ep))
|
||||
}
|
||||
|
||||
func Max(ep EmployeePList, column EmployeeField) float64 {
|
||||
max := 0.0
|
||||
|
||||
_, fieldFound := reflect.TypeOf(Employee{}).FieldByName(string(column))
|
||||
if !fieldFound {
|
||||
return max
|
||||
}
|
||||
|
||||
for _, employee := range ep {
|
||||
value := reflect.ValueOf(employee).Elem().FieldByName(string(column))
|
||||
switch value.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
max = GetMax(max, float64(value.Int()))
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
max = GetMax(max, float64(value.Uint()))
|
||||
case reflect.Float64, reflect.Float32:
|
||||
max = GetMax(max, value.Float())
|
||||
default:
|
||||
return max
|
||||
}
|
||||
}
|
||||
|
||||
return max
|
||||
}
|
||||
|
||||
func Min(ep EmployeePList, column EmployeeField) float64 {
|
||||
min := math.MaxFloat64
|
||||
|
||||
_, fieldFound := reflect.TypeOf(Employee{}).FieldByName(string(column))
|
||||
if !fieldFound {
|
||||
return min
|
||||
}
|
||||
|
||||
for _, employee := range ep {
|
||||
value := reflect.ValueOf(employee).Elem().FieldByName(string(column))
|
||||
switch value.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
min = GetMin(min, float64(value.Int()))
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
min = GetMin(min, float64(value.Uint()))
|
||||
case reflect.Float64, reflect.Float32:
|
||||
min = GetMin(min, value.Float())
|
||||
default:
|
||||
return min
|
||||
}
|
||||
}
|
||||
|
||||
return min
|
||||
}
|
||||
Reference in New Issue
Block a user