Files
pig-farm-controller/internal/infra/repository/sensor_data_repository.go
2025-10-19 14:11:18 +08:00

100 lines
3.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package repository
import (
"errors"
"time"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
"gorm.io/gorm"
)
// ErrInvalidPagination 表示分页参数无效
var ErrInvalidPagination = errors.New("无效的分页参数page和pageSize必须为大于0")
// SensorDataListOptions 定义了查询传感器数据列表时的可选参数
type SensorDataListOptions struct {
DeviceID *uint
SensorType *models.SensorType
StartTime *time.Time
EndTime *time.Time
OrderBy string // 例如 "time DESC"
}
// SensorDataRepository 定义了与传感器数据相关的数据库操作接口。
type SensorDataRepository interface {
Create(sensorData *models.SensorData) error
GetLatestSensorDataByDeviceIDAndSensorType(deviceID uint, sensorType models.SensorType) (*models.SensorData, error)
// List 支持分页和过滤的列表查询
List(opts SensorDataListOptions, page, pageSize int) ([]models.SensorData, int64, error)
}
// gormSensorDataRepository 是 SensorDataRepository 的 GORM 实现。
type gormSensorDataRepository struct {
db *gorm.DB
}
// NewGormSensorDataRepository 创建一个新的 SensorDataRepository GORM 实现实例。
func NewGormSensorDataRepository(db *gorm.DB) SensorDataRepository {
return &gormSensorDataRepository{db: db}
}
// Create 将一条新的传感器数据记录插入数据库。
func (r *gormSensorDataRepository) Create(sensorData *models.SensorData) error {
return r.db.Create(sensorData).Error
}
// GetLatestSensorDataByDeviceIDAndSensorType 根据设备ID和传感器类型查询最新的传感器数据。
func (r *gormSensorDataRepository) GetLatestSensorDataByDeviceIDAndSensorType(deviceID uint, sensorType models.SensorType) (*models.SensorData, error) {
var sensorData models.SensorData
// 增加一个时间范围来缩小查询范围, 从而加快查找速度, 当使用时序数据库时时间范围可以让数据库忽略时间靠前的分片
err := r.db.Where("device_id = ? AND sensor_type = ? AND time >=?", deviceID, sensorType, time.Now().Add(-24*time.Hour)).
Order("time DESC").
First(&sensorData).Error
return &sensorData, err
}
// List 实现了分页和过滤查询传感器数据的功能
func (r *gormSensorDataRepository) List(opts SensorDataListOptions, page, pageSize int) ([]models.SensorData, int64, error) {
// --- 校验分页参数 ---
if page <= 0 || pageSize <= 0 {
return nil, 0, ErrInvalidPagination
}
var results []models.SensorData
var total int64
query := r.db.Model(&models.SensorData{})
// --- 应用过滤条件 ---
if opts.DeviceID != nil {
query = query.Where("device_id = ?", *opts.DeviceID)
}
if opts.SensorType != nil {
query = query.Where("sensor_type = ?", *opts.SensorType)
}
if opts.StartTime != nil {
query = query.Where("time >= ?", *opts.StartTime)
}
if opts.EndTime != nil {
query = query.Where("time <= ?", *opts.EndTime)
}
// --- 计算总数 ---
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
// --- 应用排序条件 ---
orderBy := "time DESC" // 默认排序
if opts.OrderBy != "" {
orderBy = opts.OrderBy
}
query = query.Order(orderBy)
// --- 分页 ---
offset := (page - 1) * pageSize
err := query.Limit(pageSize).Offset(offset).Find(&results).Error
return results, total, err
}