package repository import ( "context" "database/sql" "fmt" "github.com/luxsin/app-api/internal/model" ) type OTARepository struct { db *sql.DB } func NewOTARepository(db *sql.DB) *OTARepository { return &OTARepository{db: db} } // GetLatestOTA 按 model+hw+beta+status=1 查询最新一条 OTA 记录(verCode 降序) func (r *OTARepository) GetLatestOTA(ctx context.Context, modelVal string, hw, beta int) (*model.OTA, error) { const query = `SELECT id, verCode, verName, url, md5, ` + "`force`" + `, ` + "`desc`" + `, model, hw, target, beta, startTime, endTime, status FROM ota WHERE model = ? AND hw = ? AND beta = ? AND status = 1 ORDER BY verCode DESC LIMIT 1` var o model.OTA var desc, mdl sql.NullString var startTime, endTime sql.NullTime err := r.db.QueryRowContext(ctx, query, modelVal, hw, beta).Scan( &o.ID, &o.VerCode, &o.VerName, &o.URL, &o.MD5, &o.Force, &desc, &mdl, &o.HW, &o.Target, &o.Beta, &startTime, &endTime, &o.Status, ) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, fmt.Errorf("query ota: %w", err) } if desc.Valid { o.Desc = &desc.String } if mdl.Valid { o.Model = &mdl.String } if startTime.Valid { o.StartTime = &startTime.Time } if endTime.Valid { o.EndTime = &endTime.Time } return &o, nil } // GetLatestOTANotInBlackList 查询最新一条不在黑名单中的 OTA 记录 func (r *OTARepository) GetLatestOTANotInBlackList(ctx context.Context, modelVal string, hw, beta int, mac string) (*model.OTA, error) { const query = `SELECT id, verCode, verName, url, md5, ` + "`force`" + `, ` + "`desc`" + `, model, hw, target, beta, startTime, endTime, status FROM ota WHERE status = 1 AND model = ? AND hw = ? AND beta = ? AND id NOT IN (SELECT ota_id FROM black_list WHERE mac = ?) ORDER BY verCode DESC LIMIT 1` var o model.OTA var desc, mdl sql.NullString var startTime, endTime sql.NullTime err := r.db.QueryRowContext(ctx, query, modelVal, hw, beta, mac).Scan( &o.ID, &o.VerCode, &o.VerName, &o.URL, &o.MD5, &o.Force, &desc, &mdl, &o.HW, &o.Target, &o.Beta, &startTime, &endTime, &o.Status, ) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, fmt.Errorf("query ota not in blacklist: %w", err) } if desc.Valid { o.Desc = &desc.String } if mdl.Valid { o.Model = &mdl.String } if startTime.Valid { o.StartTime = &startTime.Time } if endTime.Valid { o.EndTime = &endTime.Time } return &o, nil } // GetLatestOTANotTarget 查询最新一条非定向的 OTA 记录 func (r *OTARepository) GetLatestOTANotTarget(ctx context.Context, modelVal string, hw, beta int) (*model.OTA, error) { const query = `SELECT id, verCode, verName, url, md5, ` + "`force`" + `, ` + "`desc`" + `, model, hw, target, beta, startTime, endTime, status FROM ota WHERE status = 1 AND model = ? AND hw = ? AND beta = ? AND target = 0 ORDER BY verCode DESC LIMIT 1` var o model.OTA var desc, mdl sql.NullString var startTime, endTime sql.NullTime err := r.db.QueryRowContext(ctx, query, modelVal, hw, beta).Scan( &o.ID, &o.VerCode, &o.VerName, &o.URL, &o.MD5, &o.Force, &desc, &mdl, &o.HW, &o.Target, &o.Beta, &startTime, &endTime, &o.Status, ) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, fmt.Errorf("query ota not target: %w", err) } if desc.Valid { o.Desc = &desc.String } if mdl.Valid { o.Model = &mdl.String } if startTime.Valid { o.StartTime = &startTime.Time } if endTime.Valid { o.EndTime = &endTime.Time } return &o, nil } // IsInBlackList 检查 mac 是否在指定 ota_id 的黑名单中 func (r *OTARepository) IsInBlackList(ctx context.Context, otaID int, mac string) (bool, error) { const query = `SELECT COUNT(*) FROM black_list WHERE ota_id = ? AND mac = ?` var count int if err := r.db.QueryRowContext(ctx, query, otaID, mac).Scan(&count); err != nil { return false, fmt.Errorf("query black_list: %w", err) } return count > 0, nil } // FindTargetDevice 检查 mac 是否在指定 ota_id 的定向设备中 func (r *OTARepository) FindTargetDevice(ctx context.Context, otaID int, mac string) (*model.OTATargetDevice, error) { const query = `SELECT id, ota_id, mac_addr, create_at FROM ota_target_device WHERE ota_id = ? AND mac_addr = ?` var d model.OTATargetDevice err := r.db.QueryRowContext(ctx, query, otaID, mac).Scan(&d.ID, &d.OTAID, &d.MacAddr, &d.CreateAt) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, fmt.Errorf("query ota_target_device: %w", err) } return &d, nil }