321 lines
6.1 KiB
Go
321 lines
6.1 KiB
Go
package mqe
|
||
|
||
import (
|
||
"fmt"
|
||
"sort"
|
||
"strconv"
|
||
)
|
||
|
||
type GetYearIndexReq struct {
|
||
Since int64 `json:"since"` // из фильтр-формы
|
||
Until int64 `json:"until"` // из фильтр-формы
|
||
LastDayOfMonth int `json:"lastDayOfMonth"` // например, конец месяца 25 число
|
||
FirstHourOfDay int `json:"firstHourOfDay"` // например день начинается в 6:00
|
||
MetricIDs []int64 `json:"metricIDs"`
|
||
}
|
||
|
||
func (s *MeasureQueryEngine) GetYearIndex(req GetYearIndexReq) (years []int, err error) {
|
||
if len(req.MetricIDs) == 0 {
|
||
return
|
||
}
|
||
|
||
var (
|
||
lte, gte string
|
||
|
||
args = []any{
|
||
req.MetricIDs,
|
||
}
|
||
)
|
||
|
||
if req.Since > 0 {
|
||
lte = " AND tm >= ?"
|
||
args = append(args, req.Since)
|
||
}
|
||
|
||
if req.Until > 0 {
|
||
gte = " AND tm <= ?"
|
||
args = append(args, req.Until)
|
||
}
|
||
|
||
q := fmt.Sprintf(`
|
||
SELECT YEAR(FROM_UNIXTIME(tm)) as y
|
||
FROM f64
|
||
WHERE metricID IN (?)%s%s
|
||
GROUP BY y`,
|
||
lte, gte)
|
||
|
||
// fmt.Println(q)
|
||
// fmt.Printf("%v\n", args)
|
||
|
||
err = s.db.ListQuery(&years, q, args...)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
sort.Ints(years)
|
||
return
|
||
}
|
||
|
||
type GetMonthIndexReq struct {
|
||
Since int64 `json:"since"` // из фильтр-формы
|
||
Until int64 `json:"until"` // из фильтр-формы
|
||
LastDayOfMonth int `json:"lastDayOfMonth"` // например, конец месяца 25 число
|
||
FirstHourOfDay int `json:"firstHourOfDay"` // например день начинается в 6:00
|
||
MetricIDs []int64 `json:"metricIDs"`
|
||
}
|
||
|
||
type YearMonth struct {
|
||
Year int `json:"year"`
|
||
Months []int `json:"months"`
|
||
}
|
||
|
||
func (s *MeasureQueryEngine) GetMonthIndex(req GetMonthIndexReq) (years []YearMonth, err error) {
|
||
if len(req.MetricIDs) == 0 {
|
||
return
|
||
}
|
||
|
||
dt, err := getDateTimeFacingFHDAndLDM(req.FirstHourOfDay, req.LastDayOfMonth)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
var (
|
||
lte, gte string
|
||
|
||
args = []any{
|
||
req.MetricIDs,
|
||
}
|
||
)
|
||
|
||
if req.Since > 0 {
|
||
lte = " AND tm >= ?"
|
||
args = append(args, req.Since)
|
||
}
|
||
|
||
if req.Until > 0 {
|
||
gte = " AND tm <= ?"
|
||
args = append(args, req.Until)
|
||
}
|
||
|
||
// ВАЖНО!
|
||
// Не сортируем средствами MySQL чтобы не создавать временный файл
|
||
query := fmt.Sprintf(`
|
||
SELECT DATE_FORMAT(%s, '%s') as p
|
||
FROM f64
|
||
WHERE metricID IN (?)%s%s
|
||
GROUP BY p`,
|
||
dt, "%Y%m", lte, gte)
|
||
|
||
var (
|
||
temp []string
|
||
yms []int
|
||
)
|
||
|
||
err = s.db.ListQuery(&temp, query, args...)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
for _, str := range temp {
|
||
var ym int
|
||
ym, err = strconv.Atoi(str)
|
||
if err != nil {
|
||
return
|
||
}
|
||
yms = append(yms, ym)
|
||
}
|
||
return IndexYms(yms), nil
|
||
}
|
||
|
||
type GetDayIndexReq struct {
|
||
Since int64 `json:"since"` // из фильтр-формы
|
||
Until int64 `json:"until"` // из фильтр-формы
|
||
FirstHourOfDay int `json:"firstHourOfDay"` // например день начинается в 6:00
|
||
MetricIDs []int64 `json:"metricIDs"`
|
||
}
|
||
|
||
type YearMonthDay struct {
|
||
Year int `json:"year"`
|
||
Months []MonthDay `json:"months"`
|
||
}
|
||
|
||
type MonthDay struct {
|
||
Month int `json:"month"`
|
||
Days []int `json:"days"`
|
||
}
|
||
|
||
func (s *MeasureQueryEngine) GetDayIndex(req GetDayIndexReq) (years []YearMonthDay, err error) {
|
||
if len(req.MetricIDs) == 0 {
|
||
return
|
||
}
|
||
|
||
dt, err := getDateTimeFacingFHD(req.FirstHourOfDay)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
var (
|
||
lte, gte string
|
||
|
||
args = []any{
|
||
req.MetricIDs,
|
||
}
|
||
)
|
||
|
||
if req.Since > 0 {
|
||
lte = " AND tm >= ?"
|
||
args = append(args, req.Since)
|
||
}
|
||
|
||
if req.Until > 0 {
|
||
gte = " AND tm <= ?"
|
||
args = append(args, req.Until)
|
||
}
|
||
// ВАЖНО!
|
||
// Не сортируем средствами MySQL чтобы не создавать временный файл
|
||
query := fmt.Sprintf(`
|
||
SELECT DATE_FORMAT(%s, '%s') as p
|
||
FROM f64
|
||
WHERE metricID IN(?)%s%s
|
||
GROUP BY p`,
|
||
dt, "%Y%m%d", lte, gte)
|
||
|
||
//fmt.Printf("%s\n", query)
|
||
|
||
var (
|
||
temp []string
|
||
ymds []int
|
||
)
|
||
|
||
err = s.db.ListQuery(&temp, query, args...)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
//pretty.PPrintln("temp", temp)
|
||
|
||
for _, str := range temp {
|
||
var ymd int
|
||
ymd, err = strconv.Atoi(str)
|
||
if err != nil {
|
||
return
|
||
}
|
||
ymds = append(ymds, ymd)
|
||
}
|
||
|
||
return IndexYmds(ymds), nil
|
||
}
|
||
|
||
func IndexYmds(ymds []int) (years []YearMonthDay) {
|
||
if len(ymds) == 0 {
|
||
return
|
||
}
|
||
|
||
sort.Ints(ymds)
|
||
|
||
var (
|
||
months []MonthDay
|
||
days []int
|
||
year, month, day int
|
||
)
|
||
|
||
for _, ymd := range ymds {
|
||
y := ymd / 10000
|
||
m := (ymd % 10000) / 100
|
||
d := ymd % 100
|
||
|
||
if year == 0 {
|
||
// инициализация
|
||
year = y
|
||
month = m
|
||
day = d
|
||
} else {
|
||
if y != year {
|
||
days = append(days, day)
|
||
months = append(months, MonthDay{
|
||
Month: month,
|
||
Days: days,
|
||
})
|
||
years = append(years, YearMonthDay{
|
||
Year: year,
|
||
Months: months,
|
||
})
|
||
year = y
|
||
month = m
|
||
day = d
|
||
months = nil
|
||
days = nil
|
||
} else if m != month {
|
||
days = append(days, day)
|
||
months = append(months, MonthDay{
|
||
Month: month,
|
||
Days: days,
|
||
})
|
||
month = m
|
||
day = d
|
||
days = nil
|
||
} else if d != day {
|
||
days = append(days, day)
|
||
day = d
|
||
}
|
||
}
|
||
}
|
||
|
||
days = append(days, day)
|
||
months = append(months, MonthDay{
|
||
Month: month,
|
||
Days: days,
|
||
})
|
||
years = append(years, YearMonthDay{
|
||
Year: year,
|
||
Months: months,
|
||
})
|
||
return
|
||
}
|
||
|
||
func IndexYms(yms []int) (years []YearMonth) {
|
||
if len(yms) == 0 {
|
||
return
|
||
}
|
||
|
||
sort.Ints(yms)
|
||
|
||
var (
|
||
months []int
|
||
year, month int
|
||
)
|
||
|
||
for _, ym := range yms {
|
||
y := ym / 100
|
||
m := ym % 100
|
||
|
||
if year == 0 {
|
||
// инициализация
|
||
year = y
|
||
month = m
|
||
} else {
|
||
if y != year {
|
||
months = append(months, month)
|
||
years = append(years, YearMonth{
|
||
Year: year,
|
||
Months: months,
|
||
})
|
||
year = y
|
||
month = m
|
||
months = nil
|
||
} else if m != month {
|
||
months = append(months, month)
|
||
month = m
|
||
}
|
||
}
|
||
}
|
||
months = append(months, month)
|
||
years = append(years, YearMonth{
|
||
Year: year,
|
||
Months: months,
|
||
})
|
||
return
|
||
}
|
||
|
||
//SELECT DATE_FORMAT(FROM_UNIXTIME(tm), '%Y%m%d') as p FROM f64 WHERE metricID IN (50) AND tm >= 1700863200 AND tm <= 1700949599 GROUP BY p;
|