github.com/shoshinnikita/budget-manager@v0.7.1-0.20220131195411-8c46ff1c6778/internal/db/base/utils.go (about) 1 package base 2 3 import ( 4 "errors" 5 "fmt" 6 "strings" 7 "time" 8 9 "github.com/ShoshinNikita/budget-manager/internal/db/base/internal/sqlx" 10 ) 11 12 // -------------------------------------------------- 13 // DB 14 // -------------------------------------------------- 15 16 // checkMonth checks if a Month with passed id exists 17 func checkMonth(tx *sqlx.Tx, id uint) bool { 18 return checkModel(tx, "months", id) 19 } 20 21 // checkDay checks if a Day with passed id exists 22 func checkDay(tx *sqlx.Tx, id uint) bool { 23 return checkModel(tx, "days", id) 24 } 25 26 // checkIncome checks if an Income with passed id exists 27 func checkIncome(tx *sqlx.Tx, id uint) bool { 28 return checkModel(tx, "incomes", id) 29 } 30 31 // checkMonthlyPayment checks if a Monthly Payment with passed id exists 32 func checkMonthlyPayment(tx *sqlx.Tx, id uint) bool { 33 return checkModel(tx, "monthly_payments", id) 34 } 35 36 // checkSpend checks if a Spend with passed id exists 37 func checkSpend(tx *sqlx.Tx, id uint) bool { 38 return checkModel(tx, "spends", id) 39 } 40 41 // checkSpendType checks if a Spend Type with passed id exists 42 func checkSpendType(tx *sqlx.Tx, id uint) bool { 43 return checkModel(tx, "spend_types", id) 44 } 45 46 // checkModel checks if a model with passed id exists 47 func checkModel(tx *sqlx.Tx, table string, id uint) bool { 48 var c int 49 err := tx.Get(&c, fmt.Sprintf(`SELECT COUNT(*) FROM %s WHERE id = ?`, table), id) 50 if err != nil || c == 0 { 51 return false 52 } 53 return true 54 } 55 56 // -------------------------------------------------- 57 // Time 58 // -------------------------------------------------- 59 60 // daysInMonth returns number of days in a month 61 func daysInMonth(year int, month time.Month) int { 62 currentMonth := time.Date(year, month, 1, 0, 0, 0, 0, time.Local) 63 // Can just use m+1. time.Date will normalize overflowing month 64 nextMonth := time.Date(year, month+1, 1, 0, 0, 0, 0, time.Local) 65 66 days := int64(nextMonth.Sub(currentMonth)) / (int64(time.Hour) * 24) 67 68 return int(days) 69 } 70 71 type updateQueryBuilder struct { 72 table string 73 74 sets []string 75 setArgs []interface{} 76 77 whereID uint 78 } 79 80 func newUpdateQueryBuilder(table string, whereID uint) *updateQueryBuilder { 81 return &updateQueryBuilder{ 82 table: table, 83 whereID: whereID, 84 } 85 } 86 87 func (b *updateQueryBuilder) Set(column string, v interface{}) { 88 b.sets = append(b.sets, column+" = ?") 89 b.setArgs = append(b.setArgs, v) 90 } 91 92 func (b *updateQueryBuilder) ToSQL() (string, []interface{}, error) { 93 if len(b.sets) == 0 { 94 return "", nil, errors.New("list of SETs is empty") 95 } 96 97 query := fmt.Sprintf(`UPDATE %s SET %s WHERE id = ?`, b.table, strings.Join(b.sets, ", ")) 98 args := append(b.setArgs, b.whereID) //nolint:gocritic 99 return query, args, nil 100 }