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;
|