Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

queries.go 2.2KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Copyright (c) 2020 Shivaram Lingamneni <slingamn@cs.stanford.edu>
  2. // released under the MIT license
  3. package history
  4. import (
  5. "time"
  6. )
  7. // Selector represents a parameter to a CHATHISTORY command
  8. type Selector struct {
  9. Msgid string
  10. Time time.Time
  11. }
  12. // Sequence is an abstract sequence of history entries that can be queried;
  13. // it encapsulates restrictions such as registration time cutoffs, or
  14. // only looking at a single "query buffer" (DMs with a particular correspondent)
  15. type Sequence interface {
  16. Between(start, end Selector, limit int) (results []Item, complete bool, err error)
  17. Around(start Selector, limit int) (results []Item, err error)
  18. }
  19. // This is a bad, slow implementation of CHATHISTORY AROUND using the BETWEEN semantics
  20. func GenericAround(seq Sequence, start Selector, limit int) (results []Item, err error) {
  21. var halfLimit int
  22. halfLimit = (limit + 1) / 2
  23. initialResults, _, err := seq.Between(Selector{}, start, halfLimit)
  24. if err != nil {
  25. return
  26. } else if len(initialResults) == 0 {
  27. // TODO: this fails if we're doing an AROUND on the first message in the buffer
  28. // would be nice to fix this but whatever
  29. return
  30. }
  31. newStart := Selector{Time: initialResults[0].Message.Time}
  32. results, _, err = seq.Between(newStart, Selector{}, limit)
  33. return
  34. }
  35. // MinMaxAsc converts CHATHISTORY arguments into time intervals, handling the most
  36. // general case (BETWEEN going forwards or backwards) natively and the other ordering
  37. // queries (AFTER, BEFORE, LATEST) as special cases.
  38. func MinMaxAsc(after, before, cutoff time.Time) (min, max time.Time, ascending bool) {
  39. startIsZero, endIsZero := after.IsZero(), before.IsZero()
  40. if !startIsZero && endIsZero {
  41. // AFTER
  42. ascending = true
  43. } else if startIsZero && !endIsZero {
  44. // BEFORE
  45. ascending = false
  46. } else if !startIsZero && !endIsZero {
  47. if before.Before(after) {
  48. // BETWEEN going backwards
  49. before, after = after, before
  50. ascending = false
  51. } else {
  52. // BETWEEN going forwards
  53. ascending = true
  54. }
  55. } else if startIsZero && endIsZero {
  56. // LATEST
  57. ascending = false
  58. }
  59. if after.IsZero() || after.Before(cutoff) {
  60. // this may result in an impossible query, which is fine
  61. after = cutoff
  62. }
  63. return after, before, ascending
  64. }