stillbox/pkg/database/partman/intervals.go

153 lines
3.3 KiB
Go
Raw Normal View History

package partman
import (
"fmt"
"time"
)
const (
daysInWeek = 7
monthsInQuarter = 3
)
func getDailyBounds(date time.Time) (lowerBound, upperBound time.Time) {
lowerBound = time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, time.UTC)
upperBound = lowerBound.AddDate(0, 0, 1)
return
}
func getWeeklyBounds(date time.Time) (lowerBound, upperBound time.Time) {
lowerBound = time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, time.UTC).AddDate(0, 0, -int(date.Weekday()-time.Monday))
upperBound = lowerBound.AddDate(0, 0, daysInWeek)
return
}
func getMonthlyBounds(date time.Time) (lowerBound, upperBound time.Time) {
lowerBound = time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, time.UTC)
upperBound = lowerBound.AddDate(0, 1, 0)
return
}
func getQuarterlyBounds(date time.Time) (lowerBound, upperBound time.Time) {
year, _, _ := date.Date()
quarter := (int(date.Month()) - 1) / monthsInQuarter
firstMonthOfTheQuarter := time.Month(quarter*monthsInQuarter + 1)
lowerBound = time.Date(year, firstMonthOfTheQuarter, 1, 0, 0, 0, 0, time.UTC)
upperBound = lowerBound.AddDate(0, monthsInQuarter, 0)
return
}
func getYearlyBounds(date time.Time) (lowerBound, upperBound time.Time) {
lowerBound = time.Date(date.Year(), 1, 1, 0, 0, 0, 0, time.UTC)
upperBound = lowerBound.AddDate(1, 0, 0)
return
}
func (p Partition) Next(i int) Partition {
var t time.Time
switch p.Interval {
case Daily:
t = p.Time.AddDate(0, 0, i)
case Weekly:
t = p.Time.AddDate(0, 0, i*daysInWeek)
case Monthly:
year, month, _ := p.Time.Date()
t = time.Date(year, month+time.Month(i), 1, 0, 0, 0, 0, p.Time.Location())
case Quarterly:
t = p.Time.AddDate(0, i*monthsInQuarter, 0)
case Yearly:
year, _, _ := p.Time.Date()
t = time.Date(year+i, 1, 1, 0, 0, 0, 0, p.Time.Location())
}
np := Partition{
ParentTable: p.ParentTable,
Name: p.Name,
Schema: p.Schema,
Interval: p.Interval,
Time: t,
}
np.setName()
return np
}
func (p *Partition) setName() {
t := p.Time
var suffix string
switch p.Interval {
case Daily:
suffix = t.Format("2006_01_02")
case Weekly:
year, week := t.ISOWeek()
suffix = fmt.Sprintf("%d_w%02d", year, week)
case Monthly:
suffix = t.Format("2006_01")
case Quarterly:
year, month, _ := t.Date()
var quarter int
switch {
case month >= 1 && month <= 3:
quarter = 1
case month >= 4 && month <= 6:
quarter = 2
case month >= 7 && month <= 9:
quarter = 3
case month >= 10 && month <= 12:
quarter = 4
}
suffix = fmt.Sprintf("%d_q%d", year, quarter)
case Yearly:
suffix = t.Format("2006")
default:
panic(ErrInvalidInterval(p.Interval))
}
p.Name = fmt.Sprintf("%s_p_%s", p.ParentTable, suffix)
}
func (p Partition) Prev(i int) Partition {
var t time.Time
switch p.Interval {
case Daily:
t = p.Time.AddDate(0, 0, -i)
case Weekly:
t = p.Time.AddDate(0, 0, -i*daysInWeek)
case Monthly:
year, month, _ := p.Time.Date()
t = time.Date(year, month-time.Month(i), 1, 0, 0, 0, 0, p.Time.Location())
case Quarterly:
t = p.Time.AddDate(0, -i*monthsInQuarter, 0)
case Yearly:
year, _, _ := p.Time.Date()
t = time.Date(year-i, 1, 1, 0, 0, 0, 0, p.Time.Location())
}
pp := Partition{
ParentTable: p.ParentTable,
Name: p.Name,
Schema: p.Schema,
Interval: p.Interval,
Time: t,
}
pp.setName()
return pp
}