25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

951 lines
30 KiB

  1. package redis
  2. import (
  3. "context"
  4. "strconv"
  5. "github.com/redis/go-redis/v9/internal/proto"
  6. )
  7. type TimeseriesCmdable interface {
  8. TSAdd(ctx context.Context, key string, timestamp interface{}, value float64) *IntCmd
  9. TSAddWithArgs(ctx context.Context, key string, timestamp interface{}, value float64, options *TSOptions) *IntCmd
  10. TSCreate(ctx context.Context, key string) *StatusCmd
  11. TSCreateWithArgs(ctx context.Context, key string, options *TSOptions) *StatusCmd
  12. TSAlter(ctx context.Context, key string, options *TSAlterOptions) *StatusCmd
  13. TSCreateRule(ctx context.Context, sourceKey string, destKey string, aggregator Aggregator, bucketDuration int) *StatusCmd
  14. TSCreateRuleWithArgs(ctx context.Context, sourceKey string, destKey string, aggregator Aggregator, bucketDuration int, options *TSCreateRuleOptions) *StatusCmd
  15. TSIncrBy(ctx context.Context, Key string, timestamp float64) *IntCmd
  16. TSIncrByWithArgs(ctx context.Context, key string, timestamp float64, options *TSIncrDecrOptions) *IntCmd
  17. TSDecrBy(ctx context.Context, Key string, timestamp float64) *IntCmd
  18. TSDecrByWithArgs(ctx context.Context, key string, timestamp float64, options *TSIncrDecrOptions) *IntCmd
  19. TSDel(ctx context.Context, Key string, fromTimestamp int, toTimestamp int) *IntCmd
  20. TSDeleteRule(ctx context.Context, sourceKey string, destKey string) *StatusCmd
  21. TSGet(ctx context.Context, key string) *TSTimestampValueCmd
  22. TSGetWithArgs(ctx context.Context, key string, options *TSGetOptions) *TSTimestampValueCmd
  23. TSInfo(ctx context.Context, key string) *MapStringInterfaceCmd
  24. TSInfoWithArgs(ctx context.Context, key string, options *TSInfoOptions) *MapStringInterfaceCmd
  25. TSMAdd(ctx context.Context, ktvSlices [][]interface{}) *IntSliceCmd
  26. TSQueryIndex(ctx context.Context, filterExpr []string) *StringSliceCmd
  27. TSRevRange(ctx context.Context, key string, fromTimestamp int, toTimestamp int) *TSTimestampValueSliceCmd
  28. TSRevRangeWithArgs(ctx context.Context, key string, fromTimestamp int, toTimestamp int, options *TSRevRangeOptions) *TSTimestampValueSliceCmd
  29. TSRange(ctx context.Context, key string, fromTimestamp int, toTimestamp int) *TSTimestampValueSliceCmd
  30. TSRangeWithArgs(ctx context.Context, key string, fromTimestamp int, toTimestamp int, options *TSRangeOptions) *TSTimestampValueSliceCmd
  31. TSMRange(ctx context.Context, fromTimestamp int, toTimestamp int, filterExpr []string) *MapStringSliceInterfaceCmd
  32. TSMRangeWithArgs(ctx context.Context, fromTimestamp int, toTimestamp int, filterExpr []string, options *TSMRangeOptions) *MapStringSliceInterfaceCmd
  33. TSMRevRange(ctx context.Context, fromTimestamp int, toTimestamp int, filterExpr []string) *MapStringSliceInterfaceCmd
  34. TSMRevRangeWithArgs(ctx context.Context, fromTimestamp int, toTimestamp int, filterExpr []string, options *TSMRevRangeOptions) *MapStringSliceInterfaceCmd
  35. TSMGet(ctx context.Context, filters []string) *MapStringSliceInterfaceCmd
  36. TSMGetWithArgs(ctx context.Context, filters []string, options *TSMGetOptions) *MapStringSliceInterfaceCmd
  37. }
  38. type TSOptions struct {
  39. Retention int
  40. ChunkSize int
  41. Encoding string
  42. DuplicatePolicy string
  43. Labels map[string]string
  44. IgnoreMaxTimeDiff int64
  45. IgnoreMaxValDiff float64
  46. }
  47. type TSIncrDecrOptions struct {
  48. Timestamp int64
  49. Retention int
  50. ChunkSize int
  51. Uncompressed bool
  52. DuplicatePolicy string
  53. Labels map[string]string
  54. IgnoreMaxTimeDiff int64
  55. IgnoreMaxValDiff float64
  56. }
  57. type TSAlterOptions struct {
  58. Retention int
  59. ChunkSize int
  60. DuplicatePolicy string
  61. Labels map[string]string
  62. IgnoreMaxTimeDiff int64
  63. IgnoreMaxValDiff float64
  64. }
  65. type TSCreateRuleOptions struct {
  66. alignTimestamp int64
  67. }
  68. type TSGetOptions struct {
  69. Latest bool
  70. }
  71. type TSInfoOptions struct {
  72. Debug bool
  73. }
  74. type Aggregator int
  75. const (
  76. Invalid = Aggregator(iota)
  77. Avg
  78. Sum
  79. Min
  80. Max
  81. Range
  82. Count
  83. First
  84. Last
  85. StdP
  86. StdS
  87. VarP
  88. VarS
  89. Twa
  90. )
  91. func (a Aggregator) String() string {
  92. switch a {
  93. case Invalid:
  94. return ""
  95. case Avg:
  96. return "AVG"
  97. case Sum:
  98. return "SUM"
  99. case Min:
  100. return "MIN"
  101. case Max:
  102. return "MAX"
  103. case Range:
  104. return "RANGE"
  105. case Count:
  106. return "COUNT"
  107. case First:
  108. return "FIRST"
  109. case Last:
  110. return "LAST"
  111. case StdP:
  112. return "STD.P"
  113. case StdS:
  114. return "STD.S"
  115. case VarP:
  116. return "VAR.P"
  117. case VarS:
  118. return "VAR.S"
  119. case Twa:
  120. return "TWA"
  121. default:
  122. return ""
  123. }
  124. }
  125. type TSRangeOptions struct {
  126. Latest bool
  127. FilterByTS []int
  128. FilterByValue []int
  129. Count int
  130. Align interface{}
  131. Aggregator Aggregator
  132. BucketDuration int
  133. BucketTimestamp interface{}
  134. Empty bool
  135. }
  136. type TSRevRangeOptions struct {
  137. Latest bool
  138. FilterByTS []int
  139. FilterByValue []int
  140. Count int
  141. Align interface{}
  142. Aggregator Aggregator
  143. BucketDuration int
  144. BucketTimestamp interface{}
  145. Empty bool
  146. }
  147. type TSMRangeOptions struct {
  148. Latest bool
  149. FilterByTS []int
  150. FilterByValue []int
  151. WithLabels bool
  152. SelectedLabels []interface{}
  153. Count int
  154. Align interface{}
  155. Aggregator Aggregator
  156. BucketDuration int
  157. BucketTimestamp interface{}
  158. Empty bool
  159. GroupByLabel interface{}
  160. Reducer interface{}
  161. }
  162. type TSMRevRangeOptions struct {
  163. Latest bool
  164. FilterByTS []int
  165. FilterByValue []int
  166. WithLabels bool
  167. SelectedLabels []interface{}
  168. Count int
  169. Align interface{}
  170. Aggregator Aggregator
  171. BucketDuration int
  172. BucketTimestamp interface{}
  173. Empty bool
  174. GroupByLabel interface{}
  175. Reducer interface{}
  176. }
  177. type TSMGetOptions struct {
  178. Latest bool
  179. WithLabels bool
  180. SelectedLabels []interface{}
  181. }
  182. // TSAdd - Adds one or more observations to a t-digest sketch.
  183. // For more information - https://redis.io/commands/ts.add/
  184. func (c cmdable) TSAdd(ctx context.Context, key string, timestamp interface{}, value float64) *IntCmd {
  185. args := []interface{}{"TS.ADD", key, timestamp, value}
  186. cmd := NewIntCmd(ctx, args...)
  187. _ = c(ctx, cmd)
  188. return cmd
  189. }
  190. // TSAddWithArgs - Adds one or more observations to a t-digest sketch.
  191. // This function also allows for specifying additional options such as:
  192. // Retention, ChunkSize, Encoding, DuplicatePolicy and Labels.
  193. // For more information - https://redis.io/commands/ts.add/
  194. func (c cmdable) TSAddWithArgs(ctx context.Context, key string, timestamp interface{}, value float64, options *TSOptions) *IntCmd {
  195. args := []interface{}{"TS.ADD", key, timestamp, value}
  196. if options != nil {
  197. if options.Retention != 0 {
  198. args = append(args, "RETENTION", options.Retention)
  199. }
  200. if options.ChunkSize != 0 {
  201. args = append(args, "CHUNK_SIZE", options.ChunkSize)
  202. }
  203. if options.Encoding != "" {
  204. args = append(args, "ENCODING", options.Encoding)
  205. }
  206. if options.DuplicatePolicy != "" {
  207. args = append(args, "DUPLICATE_POLICY", options.DuplicatePolicy)
  208. }
  209. if options.Labels != nil {
  210. args = append(args, "LABELS")
  211. for label, value := range options.Labels {
  212. args = append(args, label, value)
  213. }
  214. }
  215. if options.IgnoreMaxTimeDiff != 0 || options.IgnoreMaxValDiff != 0 {
  216. args = append(args, "IGNORE", options.IgnoreMaxTimeDiff, options.IgnoreMaxValDiff)
  217. }
  218. }
  219. cmd := NewIntCmd(ctx, args...)
  220. _ = c(ctx, cmd)
  221. return cmd
  222. }
  223. // TSCreate - Creates a new time-series key.
  224. // For more information - https://redis.io/commands/ts.create/
  225. func (c cmdable) TSCreate(ctx context.Context, key string) *StatusCmd {
  226. args := []interface{}{"TS.CREATE", key}
  227. cmd := NewStatusCmd(ctx, args...)
  228. _ = c(ctx, cmd)
  229. return cmd
  230. }
  231. // TSCreateWithArgs - Creates a new time-series key with additional options.
  232. // This function allows for specifying additional options such as:
  233. // Retention, ChunkSize, Encoding, DuplicatePolicy and Labels.
  234. // For more information - https://redis.io/commands/ts.create/
  235. func (c cmdable) TSCreateWithArgs(ctx context.Context, key string, options *TSOptions) *StatusCmd {
  236. args := []interface{}{"TS.CREATE", key}
  237. if options != nil {
  238. if options.Retention != 0 {
  239. args = append(args, "RETENTION", options.Retention)
  240. }
  241. if options.ChunkSize != 0 {
  242. args = append(args, "CHUNK_SIZE", options.ChunkSize)
  243. }
  244. if options.Encoding != "" {
  245. args = append(args, "ENCODING", options.Encoding)
  246. }
  247. if options.DuplicatePolicy != "" {
  248. args = append(args, "DUPLICATE_POLICY", options.DuplicatePolicy)
  249. }
  250. if options.Labels != nil {
  251. args = append(args, "LABELS")
  252. for label, value := range options.Labels {
  253. args = append(args, label, value)
  254. }
  255. }
  256. if options.IgnoreMaxTimeDiff != 0 || options.IgnoreMaxValDiff != 0 {
  257. args = append(args, "IGNORE", options.IgnoreMaxTimeDiff, options.IgnoreMaxValDiff)
  258. }
  259. }
  260. cmd := NewStatusCmd(ctx, args...)
  261. _ = c(ctx, cmd)
  262. return cmd
  263. }
  264. // TSAlter - Alters an existing time-series key with additional options.
  265. // This function allows for specifying additional options such as:
  266. // Retention, ChunkSize and DuplicatePolicy.
  267. // For more information - https://redis.io/commands/ts.alter/
  268. func (c cmdable) TSAlter(ctx context.Context, key string, options *TSAlterOptions) *StatusCmd {
  269. args := []interface{}{"TS.ALTER", key}
  270. if options != nil {
  271. if options.Retention != 0 {
  272. args = append(args, "RETENTION", options.Retention)
  273. }
  274. if options.ChunkSize != 0 {
  275. args = append(args, "CHUNK_SIZE", options.ChunkSize)
  276. }
  277. if options.DuplicatePolicy != "" {
  278. args = append(args, "DUPLICATE_POLICY", options.DuplicatePolicy)
  279. }
  280. if options.Labels != nil {
  281. args = append(args, "LABELS")
  282. for label, value := range options.Labels {
  283. args = append(args, label, value)
  284. }
  285. }
  286. if options.IgnoreMaxTimeDiff != 0 || options.IgnoreMaxValDiff != 0 {
  287. args = append(args, "IGNORE", options.IgnoreMaxTimeDiff, options.IgnoreMaxValDiff)
  288. }
  289. }
  290. cmd := NewStatusCmd(ctx, args...)
  291. _ = c(ctx, cmd)
  292. return cmd
  293. }
  294. // TSCreateRule - Creates a compaction rule from sourceKey to destKey.
  295. // For more information - https://redis.io/commands/ts.createrule/
  296. func (c cmdable) TSCreateRule(ctx context.Context, sourceKey string, destKey string, aggregator Aggregator, bucketDuration int) *StatusCmd {
  297. args := []interface{}{"TS.CREATERULE", sourceKey, destKey, "AGGREGATION", aggregator.String(), bucketDuration}
  298. cmd := NewStatusCmd(ctx, args...)
  299. _ = c(ctx, cmd)
  300. return cmd
  301. }
  302. // TSCreateRuleWithArgs - Creates a compaction rule from sourceKey to destKey with additional option.
  303. // This function allows for specifying additional option such as:
  304. // alignTimestamp.
  305. // For more information - https://redis.io/commands/ts.createrule/
  306. func (c cmdable) TSCreateRuleWithArgs(ctx context.Context, sourceKey string, destKey string, aggregator Aggregator, bucketDuration int, options *TSCreateRuleOptions) *StatusCmd {
  307. args := []interface{}{"TS.CREATERULE", sourceKey, destKey, "AGGREGATION", aggregator.String(), bucketDuration}
  308. if options != nil {
  309. if options.alignTimestamp != 0 {
  310. args = append(args, options.alignTimestamp)
  311. }
  312. }
  313. cmd := NewStatusCmd(ctx, args...)
  314. _ = c(ctx, cmd)
  315. return cmd
  316. }
  317. // TSIncrBy - Increments the value of a time-series key by the specified timestamp.
  318. // For more information - https://redis.io/commands/ts.incrby/
  319. func (c cmdable) TSIncrBy(ctx context.Context, Key string, timestamp float64) *IntCmd {
  320. args := []interface{}{"TS.INCRBY", Key, timestamp}
  321. cmd := NewIntCmd(ctx, args...)
  322. _ = c(ctx, cmd)
  323. return cmd
  324. }
  325. // TSIncrByWithArgs - Increments the value of a time-series key by the specified timestamp with additional options.
  326. // This function allows for specifying additional options such as:
  327. // Timestamp, Retention, ChunkSize, Uncompressed and Labels.
  328. // For more information - https://redis.io/commands/ts.incrby/
  329. func (c cmdable) TSIncrByWithArgs(ctx context.Context, key string, timestamp float64, options *TSIncrDecrOptions) *IntCmd {
  330. args := []interface{}{"TS.INCRBY", key, timestamp}
  331. if options != nil {
  332. if options.Timestamp != 0 {
  333. args = append(args, "TIMESTAMP", options.Timestamp)
  334. }
  335. if options.Retention != 0 {
  336. args = append(args, "RETENTION", options.Retention)
  337. }
  338. if options.ChunkSize != 0 {
  339. args = append(args, "CHUNK_SIZE", options.ChunkSize)
  340. }
  341. if options.Uncompressed {
  342. args = append(args, "UNCOMPRESSED")
  343. }
  344. if options.DuplicatePolicy != "" {
  345. args = append(args, "DUPLICATE_POLICY", options.DuplicatePolicy)
  346. }
  347. if options.Labels != nil {
  348. args = append(args, "LABELS")
  349. for label, value := range options.Labels {
  350. args = append(args, label, value)
  351. }
  352. }
  353. if options.IgnoreMaxTimeDiff != 0 || options.IgnoreMaxValDiff != 0 {
  354. args = append(args, "IGNORE", options.IgnoreMaxTimeDiff, options.IgnoreMaxValDiff)
  355. }
  356. }
  357. cmd := NewIntCmd(ctx, args...)
  358. _ = c(ctx, cmd)
  359. return cmd
  360. }
  361. // TSDecrBy - Decrements the value of a time-series key by the specified timestamp.
  362. // For more information - https://redis.io/commands/ts.decrby/
  363. func (c cmdable) TSDecrBy(ctx context.Context, Key string, timestamp float64) *IntCmd {
  364. args := []interface{}{"TS.DECRBY", Key, timestamp}
  365. cmd := NewIntCmd(ctx, args...)
  366. _ = c(ctx, cmd)
  367. return cmd
  368. }
  369. // TSDecrByWithArgs - Decrements the value of a time-series key by the specified timestamp with additional options.
  370. // This function allows for specifying additional options such as:
  371. // Timestamp, Retention, ChunkSize, Uncompressed and Labels.
  372. // For more information - https://redis.io/commands/ts.decrby/
  373. func (c cmdable) TSDecrByWithArgs(ctx context.Context, key string, timestamp float64, options *TSIncrDecrOptions) *IntCmd {
  374. args := []interface{}{"TS.DECRBY", key, timestamp}
  375. if options != nil {
  376. if options.Timestamp != 0 {
  377. args = append(args, "TIMESTAMP", options.Timestamp)
  378. }
  379. if options.Retention != 0 {
  380. args = append(args, "RETENTION", options.Retention)
  381. }
  382. if options.ChunkSize != 0 {
  383. args = append(args, "CHUNK_SIZE", options.ChunkSize)
  384. }
  385. if options.Uncompressed {
  386. args = append(args, "UNCOMPRESSED")
  387. }
  388. if options.DuplicatePolicy != "" {
  389. args = append(args, "DUPLICATE_POLICY", options.DuplicatePolicy)
  390. }
  391. if options.Labels != nil {
  392. args = append(args, "LABELS")
  393. for label, value := range options.Labels {
  394. args = append(args, label, value)
  395. }
  396. }
  397. if options.IgnoreMaxTimeDiff != 0 || options.IgnoreMaxValDiff != 0 {
  398. args = append(args, "IGNORE", options.IgnoreMaxTimeDiff, options.IgnoreMaxValDiff)
  399. }
  400. }
  401. cmd := NewIntCmd(ctx, args...)
  402. _ = c(ctx, cmd)
  403. return cmd
  404. }
  405. // TSDel - Deletes a range of samples from a time-series key.
  406. // For more information - https://redis.io/commands/ts.del/
  407. func (c cmdable) TSDel(ctx context.Context, Key string, fromTimestamp int, toTimestamp int) *IntCmd {
  408. args := []interface{}{"TS.DEL", Key, fromTimestamp, toTimestamp}
  409. cmd := NewIntCmd(ctx, args...)
  410. _ = c(ctx, cmd)
  411. return cmd
  412. }
  413. // TSDeleteRule - Deletes a compaction rule from sourceKey to destKey.
  414. // For more information - https://redis.io/commands/ts.deleterule/
  415. func (c cmdable) TSDeleteRule(ctx context.Context, sourceKey string, destKey string) *StatusCmd {
  416. args := []interface{}{"TS.DELETERULE", sourceKey, destKey}
  417. cmd := NewStatusCmd(ctx, args...)
  418. _ = c(ctx, cmd)
  419. return cmd
  420. }
  421. // TSGetWithArgs - Gets the last sample of a time-series key with additional option.
  422. // This function allows for specifying additional option such as:
  423. // Latest.
  424. // For more information - https://redis.io/commands/ts.get/
  425. func (c cmdable) TSGetWithArgs(ctx context.Context, key string, options *TSGetOptions) *TSTimestampValueCmd {
  426. args := []interface{}{"TS.GET", key}
  427. if options != nil {
  428. if options.Latest {
  429. args = append(args, "LATEST")
  430. }
  431. }
  432. cmd := newTSTimestampValueCmd(ctx, args...)
  433. _ = c(ctx, cmd)
  434. return cmd
  435. }
  436. // TSGet - Gets the last sample of a time-series key.
  437. // For more information - https://redis.io/commands/ts.get/
  438. func (c cmdable) TSGet(ctx context.Context, key string) *TSTimestampValueCmd {
  439. args := []interface{}{"TS.GET", key}
  440. cmd := newTSTimestampValueCmd(ctx, args...)
  441. _ = c(ctx, cmd)
  442. return cmd
  443. }
  444. type TSTimestampValue struct {
  445. Timestamp int64
  446. Value float64
  447. }
  448. type TSTimestampValueCmd struct {
  449. baseCmd
  450. val TSTimestampValue
  451. }
  452. func newTSTimestampValueCmd(ctx context.Context, args ...interface{}) *TSTimestampValueCmd {
  453. return &TSTimestampValueCmd{
  454. baseCmd: baseCmd{
  455. ctx: ctx,
  456. args: args,
  457. },
  458. }
  459. }
  460. func (cmd *TSTimestampValueCmd) String() string {
  461. return cmdString(cmd, cmd.val)
  462. }
  463. func (cmd *TSTimestampValueCmd) SetVal(val TSTimestampValue) {
  464. cmd.val = val
  465. }
  466. func (cmd *TSTimestampValueCmd) Result() (TSTimestampValue, error) {
  467. return cmd.val, cmd.err
  468. }
  469. func (cmd *TSTimestampValueCmd) Val() TSTimestampValue {
  470. return cmd.val
  471. }
  472. func (cmd *TSTimestampValueCmd) readReply(rd *proto.Reader) (err error) {
  473. n, err := rd.ReadMapLen()
  474. if err != nil {
  475. return err
  476. }
  477. cmd.val = TSTimestampValue{}
  478. for i := 0; i < n; i++ {
  479. timestamp, err := rd.ReadInt()
  480. if err != nil {
  481. return err
  482. }
  483. value, err := rd.ReadString()
  484. if err != nil {
  485. return err
  486. }
  487. cmd.val.Timestamp = timestamp
  488. cmd.val.Value, err = strconv.ParseFloat(value, 64)
  489. if err != nil {
  490. return err
  491. }
  492. }
  493. return nil
  494. }
  495. // TSInfo - Returns information about a time-series key.
  496. // For more information - https://redis.io/commands/ts.info/
  497. func (c cmdable) TSInfo(ctx context.Context, key string) *MapStringInterfaceCmd {
  498. args := []interface{}{"TS.INFO", key}
  499. cmd := NewMapStringInterfaceCmd(ctx, args...)
  500. _ = c(ctx, cmd)
  501. return cmd
  502. }
  503. // TSInfoWithArgs - Returns information about a time-series key with additional option.
  504. // This function allows for specifying additional option such as:
  505. // Debug.
  506. // For more information - https://redis.io/commands/ts.info/
  507. func (c cmdable) TSInfoWithArgs(ctx context.Context, key string, options *TSInfoOptions) *MapStringInterfaceCmd {
  508. args := []interface{}{"TS.INFO", key}
  509. if options != nil {
  510. if options.Debug {
  511. args = append(args, "DEBUG")
  512. }
  513. }
  514. cmd := NewMapStringInterfaceCmd(ctx, args...)
  515. _ = c(ctx, cmd)
  516. return cmd
  517. }
  518. // TSMAdd - Adds multiple samples to multiple time-series keys.
  519. // It accepts a slice of 'ktv' slices, each containing exactly three elements: key, timestamp, and value.
  520. // This struct must be provided for this command to work.
  521. // For more information - https://redis.io/commands/ts.madd/
  522. func (c cmdable) TSMAdd(ctx context.Context, ktvSlices [][]interface{}) *IntSliceCmd {
  523. args := []interface{}{"TS.MADD"}
  524. for _, ktv := range ktvSlices {
  525. args = append(args, ktv...)
  526. }
  527. cmd := NewIntSliceCmd(ctx, args...)
  528. _ = c(ctx, cmd)
  529. return cmd
  530. }
  531. // TSQueryIndex - Returns all the keys matching the filter expression.
  532. // For more information - https://redis.io/commands/ts.queryindex/
  533. func (c cmdable) TSQueryIndex(ctx context.Context, filterExpr []string) *StringSliceCmd {
  534. args := []interface{}{"TS.QUERYINDEX"}
  535. for _, f := range filterExpr {
  536. args = append(args, f)
  537. }
  538. cmd := NewStringSliceCmd(ctx, args...)
  539. _ = c(ctx, cmd)
  540. return cmd
  541. }
  542. // TSRevRange - Returns a range of samples from a time-series key in reverse order.
  543. // For more information - https://redis.io/commands/ts.revrange/
  544. func (c cmdable) TSRevRange(ctx context.Context, key string, fromTimestamp int, toTimestamp int) *TSTimestampValueSliceCmd {
  545. args := []interface{}{"TS.REVRANGE", key, fromTimestamp, toTimestamp}
  546. cmd := newTSTimestampValueSliceCmd(ctx, args...)
  547. _ = c(ctx, cmd)
  548. return cmd
  549. }
  550. // TSRevRangeWithArgs - Returns a range of samples from a time-series key in reverse order with additional options.
  551. // This function allows for specifying additional options such as:
  552. // Latest, FilterByTS, FilterByValue, Count, Align, Aggregator,
  553. // BucketDuration, BucketTimestamp and Empty.
  554. // For more information - https://redis.io/commands/ts.revrange/
  555. func (c cmdable) TSRevRangeWithArgs(ctx context.Context, key string, fromTimestamp int, toTimestamp int, options *TSRevRangeOptions) *TSTimestampValueSliceCmd {
  556. args := []interface{}{"TS.REVRANGE", key, fromTimestamp, toTimestamp}
  557. if options != nil {
  558. if options.Latest {
  559. args = append(args, "LATEST")
  560. }
  561. if options.FilterByTS != nil {
  562. args = append(args, "FILTER_BY_TS")
  563. for _, f := range options.FilterByTS {
  564. args = append(args, f)
  565. }
  566. }
  567. if options.FilterByValue != nil {
  568. args = append(args, "FILTER_BY_VALUE")
  569. for _, f := range options.FilterByValue {
  570. args = append(args, f)
  571. }
  572. }
  573. if options.Count != 0 {
  574. args = append(args, "COUNT", options.Count)
  575. }
  576. if options.Align != nil {
  577. args = append(args, "ALIGN", options.Align)
  578. }
  579. if options.Aggregator != 0 {
  580. args = append(args, "AGGREGATION", options.Aggregator.String())
  581. }
  582. if options.BucketDuration != 0 {
  583. args = append(args, options.BucketDuration)
  584. }
  585. if options.BucketTimestamp != nil {
  586. args = append(args, "BUCKETTIMESTAMP", options.BucketTimestamp)
  587. }
  588. if options.Empty {
  589. args = append(args, "EMPTY")
  590. }
  591. }
  592. cmd := newTSTimestampValueSliceCmd(ctx, args...)
  593. _ = c(ctx, cmd)
  594. return cmd
  595. }
  596. // TSRange - Returns a range of samples from a time-series key.
  597. // For more information - https://redis.io/commands/ts.range/
  598. func (c cmdable) TSRange(ctx context.Context, key string, fromTimestamp int, toTimestamp int) *TSTimestampValueSliceCmd {
  599. args := []interface{}{"TS.RANGE", key, fromTimestamp, toTimestamp}
  600. cmd := newTSTimestampValueSliceCmd(ctx, args...)
  601. _ = c(ctx, cmd)
  602. return cmd
  603. }
  604. // TSRangeWithArgs - Returns a range of samples from a time-series key with additional options.
  605. // This function allows for specifying additional options such as:
  606. // Latest, FilterByTS, FilterByValue, Count, Align, Aggregator,
  607. // BucketDuration, BucketTimestamp and Empty.
  608. // For more information - https://redis.io/commands/ts.range/
  609. func (c cmdable) TSRangeWithArgs(ctx context.Context, key string, fromTimestamp int, toTimestamp int, options *TSRangeOptions) *TSTimestampValueSliceCmd {
  610. args := []interface{}{"TS.RANGE", key, fromTimestamp, toTimestamp}
  611. if options != nil {
  612. if options.Latest {
  613. args = append(args, "LATEST")
  614. }
  615. if options.FilterByTS != nil {
  616. args = append(args, "FILTER_BY_TS")
  617. for _, f := range options.FilterByTS {
  618. args = append(args, f)
  619. }
  620. }
  621. if options.FilterByValue != nil {
  622. args = append(args, "FILTER_BY_VALUE")
  623. for _, f := range options.FilterByValue {
  624. args = append(args, f)
  625. }
  626. }
  627. if options.Count != 0 {
  628. args = append(args, "COUNT", options.Count)
  629. }
  630. if options.Align != nil {
  631. args = append(args, "ALIGN", options.Align)
  632. }
  633. if options.Aggregator != 0 {
  634. args = append(args, "AGGREGATION", options.Aggregator.String())
  635. }
  636. if options.BucketDuration != 0 {
  637. args = append(args, options.BucketDuration)
  638. }
  639. if options.BucketTimestamp != nil {
  640. args = append(args, "BUCKETTIMESTAMP", options.BucketTimestamp)
  641. }
  642. if options.Empty {
  643. args = append(args, "EMPTY")
  644. }
  645. }
  646. cmd := newTSTimestampValueSliceCmd(ctx, args...)
  647. _ = c(ctx, cmd)
  648. return cmd
  649. }
  650. type TSTimestampValueSliceCmd struct {
  651. baseCmd
  652. val []TSTimestampValue
  653. }
  654. func newTSTimestampValueSliceCmd(ctx context.Context, args ...interface{}) *TSTimestampValueSliceCmd {
  655. return &TSTimestampValueSliceCmd{
  656. baseCmd: baseCmd{
  657. ctx: ctx,
  658. args: args,
  659. },
  660. }
  661. }
  662. func (cmd *TSTimestampValueSliceCmd) String() string {
  663. return cmdString(cmd, cmd.val)
  664. }
  665. func (cmd *TSTimestampValueSliceCmd) SetVal(val []TSTimestampValue) {
  666. cmd.val = val
  667. }
  668. func (cmd *TSTimestampValueSliceCmd) Result() ([]TSTimestampValue, error) {
  669. return cmd.val, cmd.err
  670. }
  671. func (cmd *TSTimestampValueSliceCmd) Val() []TSTimestampValue {
  672. return cmd.val
  673. }
  674. func (cmd *TSTimestampValueSliceCmd) readReply(rd *proto.Reader) (err error) {
  675. n, err := rd.ReadArrayLen()
  676. if err != nil {
  677. return err
  678. }
  679. cmd.val = make([]TSTimestampValue, n)
  680. for i := 0; i < n; i++ {
  681. _, _ = rd.ReadArrayLen()
  682. timestamp, err := rd.ReadInt()
  683. if err != nil {
  684. return err
  685. }
  686. value, err := rd.ReadString()
  687. if err != nil {
  688. return err
  689. }
  690. cmd.val[i].Timestamp = timestamp
  691. cmd.val[i].Value, err = strconv.ParseFloat(value, 64)
  692. if err != nil {
  693. return err
  694. }
  695. }
  696. return nil
  697. }
  698. // TSMRange - Returns a range of samples from multiple time-series keys.
  699. // For more information - https://redis.io/commands/ts.mrange/
  700. func (c cmdable) TSMRange(ctx context.Context, fromTimestamp int, toTimestamp int, filterExpr []string) *MapStringSliceInterfaceCmd {
  701. args := []interface{}{"TS.MRANGE", fromTimestamp, toTimestamp, "FILTER"}
  702. for _, f := range filterExpr {
  703. args = append(args, f)
  704. }
  705. cmd := NewMapStringSliceInterfaceCmd(ctx, args...)
  706. _ = c(ctx, cmd)
  707. return cmd
  708. }
  709. // TSMRangeWithArgs - Returns a range of samples from multiple time-series keys with additional options.
  710. // This function allows for specifying additional options such as:
  711. // Latest, FilterByTS, FilterByValue, WithLabels, SelectedLabels,
  712. // Count, Align, Aggregator, BucketDuration, BucketTimestamp,
  713. // Empty, GroupByLabel and Reducer.
  714. // For more information - https://redis.io/commands/ts.mrange/
  715. func (c cmdable) TSMRangeWithArgs(ctx context.Context, fromTimestamp int, toTimestamp int, filterExpr []string, options *TSMRangeOptions) *MapStringSliceInterfaceCmd {
  716. args := []interface{}{"TS.MRANGE", fromTimestamp, toTimestamp}
  717. if options != nil {
  718. if options.Latest {
  719. args = append(args, "LATEST")
  720. }
  721. if options.FilterByTS != nil {
  722. args = append(args, "FILTER_BY_TS")
  723. for _, f := range options.FilterByTS {
  724. args = append(args, f)
  725. }
  726. }
  727. if options.FilterByValue != nil {
  728. args = append(args, "FILTER_BY_VALUE")
  729. for _, f := range options.FilterByValue {
  730. args = append(args, f)
  731. }
  732. }
  733. if options.WithLabels {
  734. args = append(args, "WITHLABELS")
  735. }
  736. if options.SelectedLabels != nil {
  737. args = append(args, "SELECTED_LABELS")
  738. args = append(args, options.SelectedLabels...)
  739. }
  740. if options.Count != 0 {
  741. args = append(args, "COUNT", options.Count)
  742. }
  743. if options.Align != nil {
  744. args = append(args, "ALIGN", options.Align)
  745. }
  746. if options.Aggregator != 0 {
  747. args = append(args, "AGGREGATION", options.Aggregator.String())
  748. }
  749. if options.BucketDuration != 0 {
  750. args = append(args, options.BucketDuration)
  751. }
  752. if options.BucketTimestamp != nil {
  753. args = append(args, "BUCKETTIMESTAMP", options.BucketTimestamp)
  754. }
  755. if options.Empty {
  756. args = append(args, "EMPTY")
  757. }
  758. }
  759. args = append(args, "FILTER")
  760. for _, f := range filterExpr {
  761. args = append(args, f)
  762. }
  763. if options != nil {
  764. if options.GroupByLabel != nil {
  765. args = append(args, "GROUPBY", options.GroupByLabel)
  766. }
  767. if options.Reducer != nil {
  768. args = append(args, "REDUCE", options.Reducer)
  769. }
  770. }
  771. cmd := NewMapStringSliceInterfaceCmd(ctx, args...)
  772. _ = c(ctx, cmd)
  773. return cmd
  774. }
  775. // TSMRevRange - Returns a range of samples from multiple time-series keys in reverse order.
  776. // For more information - https://redis.io/commands/ts.mrevrange/
  777. func (c cmdable) TSMRevRange(ctx context.Context, fromTimestamp int, toTimestamp int, filterExpr []string) *MapStringSliceInterfaceCmd {
  778. args := []interface{}{"TS.MREVRANGE", fromTimestamp, toTimestamp, "FILTER"}
  779. for _, f := range filterExpr {
  780. args = append(args, f)
  781. }
  782. cmd := NewMapStringSliceInterfaceCmd(ctx, args...)
  783. _ = c(ctx, cmd)
  784. return cmd
  785. }
  786. // TSMRevRangeWithArgs - Returns a range of samples from multiple time-series keys in reverse order with additional options.
  787. // This function allows for specifying additional options such as:
  788. // Latest, FilterByTS, FilterByValue, WithLabels, SelectedLabels,
  789. // Count, Align, Aggregator, BucketDuration, BucketTimestamp,
  790. // Empty, GroupByLabel and Reducer.
  791. // For more information - https://redis.io/commands/ts.mrevrange/
  792. func (c cmdable) TSMRevRangeWithArgs(ctx context.Context, fromTimestamp int, toTimestamp int, filterExpr []string, options *TSMRevRangeOptions) *MapStringSliceInterfaceCmd {
  793. args := []interface{}{"TS.MREVRANGE", fromTimestamp, toTimestamp}
  794. if options != nil {
  795. if options.Latest {
  796. args = append(args, "LATEST")
  797. }
  798. if options.FilterByTS != nil {
  799. args = append(args, "FILTER_BY_TS")
  800. for _, f := range options.FilterByTS {
  801. args = append(args, f)
  802. }
  803. }
  804. if options.FilterByValue != nil {
  805. args = append(args, "FILTER_BY_VALUE")
  806. for _, f := range options.FilterByValue {
  807. args = append(args, f)
  808. }
  809. }
  810. if options.WithLabels {
  811. args = append(args, "WITHLABELS")
  812. }
  813. if options.SelectedLabels != nil {
  814. args = append(args, "SELECTED_LABELS")
  815. args = append(args, options.SelectedLabels...)
  816. }
  817. if options.Count != 0 {
  818. args = append(args, "COUNT", options.Count)
  819. }
  820. if options.Align != nil {
  821. args = append(args, "ALIGN", options.Align)
  822. }
  823. if options.Aggregator != 0 {
  824. args = append(args, "AGGREGATION", options.Aggregator.String())
  825. }
  826. if options.BucketDuration != 0 {
  827. args = append(args, options.BucketDuration)
  828. }
  829. if options.BucketTimestamp != nil {
  830. args = append(args, "BUCKETTIMESTAMP", options.BucketTimestamp)
  831. }
  832. if options.Empty {
  833. args = append(args, "EMPTY")
  834. }
  835. }
  836. args = append(args, "FILTER")
  837. for _, f := range filterExpr {
  838. args = append(args, f)
  839. }
  840. if options != nil {
  841. if options.GroupByLabel != nil {
  842. args = append(args, "GROUPBY", options.GroupByLabel)
  843. }
  844. if options.Reducer != nil {
  845. args = append(args, "REDUCE", options.Reducer)
  846. }
  847. }
  848. cmd := NewMapStringSliceInterfaceCmd(ctx, args...)
  849. _ = c(ctx, cmd)
  850. return cmd
  851. }
  852. // TSMGet - Returns the last sample of multiple time-series keys.
  853. // For more information - https://redis.io/commands/ts.mget/
  854. func (c cmdable) TSMGet(ctx context.Context, filters []string) *MapStringSliceInterfaceCmd {
  855. args := []interface{}{"TS.MGET", "FILTER"}
  856. for _, f := range filters {
  857. args = append(args, f)
  858. }
  859. cmd := NewMapStringSliceInterfaceCmd(ctx, args...)
  860. _ = c(ctx, cmd)
  861. return cmd
  862. }
  863. // TSMGetWithArgs - Returns the last sample of multiple time-series keys with additional options.
  864. // This function allows for specifying additional options such as:
  865. // Latest, WithLabels and SelectedLabels.
  866. // For more information - https://redis.io/commands/ts.mget/
  867. func (c cmdable) TSMGetWithArgs(ctx context.Context, filters []string, options *TSMGetOptions) *MapStringSliceInterfaceCmd {
  868. args := []interface{}{"TS.MGET"}
  869. if options != nil {
  870. if options.Latest {
  871. args = append(args, "LATEST")
  872. }
  873. if options.WithLabels {
  874. args = append(args, "WITHLABELS")
  875. }
  876. if options.SelectedLabels != nil {
  877. args = append(args, "SELECTED_LABELS")
  878. args = append(args, options.SelectedLabels...)
  879. }
  880. }
  881. args = append(args, "FILTER")
  882. for _, f := range filters {
  883. args = append(args, f)
  884. }
  885. cmd := NewMapStringSliceInterfaceCmd(ctx, args...)
  886. _ = c(ctx, cmd)
  887. return cmd
  888. }