Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

67 linhas
1.2 KiB

  1. package redis
  2. import (
  3. "context"
  4. )
  5. // ScanIterator is used to incrementally iterate over a collection of elements.
  6. type ScanIterator struct {
  7. cmd *ScanCmd
  8. pos int
  9. }
  10. // Err returns the last iterator error, if any.
  11. func (it *ScanIterator) Err() error {
  12. return it.cmd.Err()
  13. }
  14. // Next advances the cursor and returns true if more values can be read.
  15. func (it *ScanIterator) Next(ctx context.Context) bool {
  16. // Instantly return on errors.
  17. if it.cmd.Err() != nil {
  18. return false
  19. }
  20. // Advance cursor, check if we are still within range.
  21. if it.pos < len(it.cmd.page) {
  22. it.pos++
  23. return true
  24. }
  25. for {
  26. // Return if there is no more data to fetch.
  27. if it.cmd.cursor == 0 {
  28. return false
  29. }
  30. // Fetch next page.
  31. switch it.cmd.args[0] {
  32. case "scan", "qscan":
  33. it.cmd.args[1] = it.cmd.cursor
  34. default:
  35. it.cmd.args[2] = it.cmd.cursor
  36. }
  37. err := it.cmd.process(ctx, it.cmd)
  38. if err != nil {
  39. return false
  40. }
  41. it.pos = 1
  42. // Redis can occasionally return empty page.
  43. if len(it.cmd.page) > 0 {
  44. return true
  45. }
  46. }
  47. }
  48. // Val returns the key/field at the current cursor position.
  49. func (it *ScanIterator) Val() string {
  50. var v string
  51. if it.cmd.Err() == nil && it.pos > 0 && it.pos <= len(it.cmd.page) {
  52. v = it.cmd.page[it.pos-1]
  53. }
  54. return v
  55. }