Use sql query to leverage sqlite speed
This commit is contained in:
parent
3f163309ad
commit
9d172a41b6
|
|
@ -14,13 +14,6 @@ type sensorValue struct {
|
|||
Value float64 `json:"value"`
|
||||
}
|
||||
|
||||
func min(a, b int64) int64 {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func (s *SensorValuesService) Push(sensorId int64, value float64) (int64, error) {
|
||||
res, err := s.ctx.DB.Exec("INSERT INTO sensor_values (timestamp, sensor_id, value) VALUES (?, ?, ?)", time.Now().Unix(), sensorId, value)
|
||||
|
||||
|
|
@ -32,36 +25,7 @@ func (s *SensorValuesService) Push(sensorId int64, value float64) (int64, error)
|
|||
}
|
||||
|
||||
func (s *SensorValuesService) GetList(sensorId int64, from int64, to int64) ([]sensorValue, error) {
|
||||
intervalSize := to - from
|
||||
batchSize := intervalSize
|
||||
|
||||
if intervalSize > 100*24*60 {
|
||||
batchSize = 24 * 60
|
||||
}
|
||||
|
||||
values := make([]sensorValue, 0)
|
||||
current := from
|
||||
|
||||
for current < to {
|
||||
nextValue := min(to, current+batchSize)
|
||||
|
||||
batchValues, err := s.getValueItems(sensorId, current, nextValue)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sum := 0.0
|
||||
|
||||
for _, item := range batchValues {
|
||||
sum += item.Value
|
||||
}
|
||||
|
||||
values = append(values, sensorValue{Timestamp: int64((nextValue + current) / 2.0), Value: sum / float64(len(batchValues))})
|
||||
current += batchSize
|
||||
}
|
||||
|
||||
return values, nil
|
||||
return s.getValueItems(sensorId, from, to, getAutoSensorValuesInterval(from, to))
|
||||
}
|
||||
|
||||
func (s *SensorValuesService) GetLatest(sensorId int64, to int64) (*sensorValue, error) {
|
||||
|
|
@ -77,10 +41,47 @@ func (s *SensorValuesService) GetLatest(sensorId int64, to int64) (*sensorValue,
|
|||
return &value, nil
|
||||
}
|
||||
|
||||
func (s *SensorValuesService) getValueItems(sensorId int64, from int64, to int64) ([]sensorValue, error) {
|
||||
func (s *SensorValuesService) getValueListQuery(sensorId int64, from int64, to int64, divide int64) (*sql.Rows, error) {
|
||||
if divide == 1 {
|
||||
return s.ctx.DB.Query("SELECT timestamp, value FROM sensor_values WHERE sensor_id = ? AND timestamp > ? AND timestamp < ? ORDER BY timestamp ASC", sensorId, from, to)
|
||||
}
|
||||
|
||||
return s.ctx.DB.Query(
|
||||
"SELECT (timestamp/?)*?, AVG(value) FROM sensor_values WHERE sensor_id = ? AND timestamp > ? AND timestamp < ? GROUP BY (timestamp/?) ORDER BY timestamp ASC",
|
||||
divide,
|
||||
divide,
|
||||
sensorId,
|
||||
from,
|
||||
to,
|
||||
divide,
|
||||
)
|
||||
}
|
||||
|
||||
func getAutoSensorValuesInterval(from int64, to int64) int64 {
|
||||
diff := to - from
|
||||
|
||||
// 360 days -> 1 day interval
|
||||
if diff > 360*24*60*60 {
|
||||
return 24 * 60 * 60
|
||||
}
|
||||
|
||||
// 160 days -> 1 hour interval
|
||||
if diff > 160*24*60*60 {
|
||||
return 60 * 60
|
||||
}
|
||||
|
||||
// 80 days -> 10 minutes
|
||||
if diff > 80*24*60*60 {
|
||||
return 10 * 60
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
func (s *SensorValuesService) getValueItems(sensorId int64, from int64, to int64, divide int64) ([]sensorValue, error) {
|
||||
values := make([]sensorValue, 0)
|
||||
|
||||
rows, err := s.ctx.DB.Query("SELECT timestamp, value FROM sensor_values WHERE sensor_id = ? AND timestamp > ? AND timestamp < ? ORDER BY timestamp ASC", sensorId, from, to)
|
||||
rows, err := s.getValueListQuery(sensorId, from, to, divide)
|
||||
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
|
|
|
|||
Loading…
Reference in New Issue