@@ -318,7 +318,7 @@ zstoreInternal
318
318
-> ByteString -- ^ destination
319
319
-> [ByteString ] -- ^ keys
320
320
-> [Double ] -- ^ weights
321
- -> Aggregate
321
+ -> Aggregate
322
322
-> m (f Integer )
323
323
zstoreInternal cmd dest keys weights aggregate = sendRequest $
324
324
concat [ [cmd, dest, encode . toInteger $ length keys], keys
@@ -638,3 +638,117 @@ exists
638
638
=> ByteString -- ^ key
639
639
-> m (f Bool )
640
640
exists key = sendRequest [" EXISTS" , key]
641
+
642
+ newtype Cursor = Cursor ByteString deriving (Show , Eq )
643
+
644
+
645
+ instance RedisArg Cursor where
646
+ encode (Cursor c) = encode c
647
+
648
+
649
+ instance RedisResult Cursor where
650
+ decode (Bulk (Just s)) = Right $ Cursor s
651
+ decode r = Left r
652
+
653
+
654
+ cursor0 :: Cursor
655
+ cursor0 = Cursor " 0"
656
+
657
+
658
+ scan
659
+ :: (RedisCtx m f )
660
+ => Cursor
661
+ -> m (f (Cursor , [ByteString ])) -- ^ next cursor and values
662
+ scan cursor = scanOpts cursor defaultScanOpts
663
+
664
+
665
+ data ScanOpts = ScanOpts
666
+ { scanMatch :: Maybe ByteString
667
+ , scanCount :: Maybe Integer
668
+ } deriving (Show , Eq )
669
+
670
+
671
+ -- | Redis default 'ScanOpts'. Equivalent to omitting all optional parameters.
672
+ --
673
+ -- @
674
+ -- ScanOpts
675
+ -- { scanMatch = Nothing -- don't match any pattern
676
+ -- , scanCount = Nothing -- don't set any requirements on number elements returned (works like value @COUNT 10@)
677
+ -- }
678
+ -- @
679
+ --
680
+ defaultScanOpts :: ScanOpts
681
+ defaultScanOpts = ScanOpts
682
+ { scanMatch = Nothing
683
+ , scanCount = Nothing
684
+ }
685
+
686
+
687
+ scanOpts
688
+ :: (RedisCtx m f )
689
+ => Cursor
690
+ -> ScanOpts
691
+ -> m (f (Cursor , [ByteString ])) -- ^ next cursor and values
692
+ scanOpts cursor opts = sendRequest $ addScanOpts [" SCAN" , encode cursor] opts
693
+
694
+
695
+ addScanOpts
696
+ :: [ByteString ] -- ^ main part of scan command
697
+ -> ScanOpts
698
+ -> [ByteString ]
699
+ addScanOpts cmd ScanOpts {.. } =
700
+ concat [cmd, match, count]
701
+ where
702
+ match = maybeToList scanMatch
703
+ count = map encode $ maybeToList scanCount
704
+
705
+
706
+ sscan
707
+ :: (RedisCtx m f )
708
+ => ByteString -- ^ key
709
+ -> Cursor
710
+ -> m (f (Cursor , [ByteString ])) -- ^ next cursor and values
711
+ sscan key cursor = sscanOpts key cursor defaultScanOpts
712
+
713
+
714
+ sscanOpts
715
+ :: (RedisCtx m f )
716
+ => ByteString -- ^ key
717
+ -> Cursor
718
+ -> ScanOpts
719
+ -> m (f (Cursor , [ByteString ])) -- ^ next cursor and values
720
+ sscanOpts key cursor opts = sendRequest $ addScanOpts [" SSCAN" , key, encode cursor] opts
721
+
722
+
723
+ hscan
724
+ :: (RedisCtx m f )
725
+ => ByteString -- ^ key
726
+ -> Cursor
727
+ -> m (f (Cursor , [(ByteString , ByteString )])) -- ^ next cursor and values
728
+ hscan key cursor = hscanOpts key cursor defaultScanOpts
729
+
730
+
731
+ hscanOpts
732
+ :: (RedisCtx m f )
733
+ => ByteString -- ^ key
734
+ -> Cursor
735
+ -> ScanOpts
736
+ -> m (f (Cursor , [(ByteString , ByteString )])) -- ^ next cursor and values
737
+ hscanOpts key cursor opts = sendRequest $ addScanOpts [" HSCAN" , key, encode cursor] opts
738
+
739
+
740
+ zscan
741
+ :: (RedisCtx m f )
742
+ => ByteString -- ^ key
743
+ -> Cursor
744
+ -> m (f (Cursor , [(ByteString , Double )])) -- ^ next cursor and values
745
+ zscan key cursor = zscanOpts key cursor defaultScanOpts
746
+
747
+
748
+ zscanOpts
749
+ :: (RedisCtx m f )
750
+ => ByteString -- ^ key
751
+ -> Cursor
752
+ -> ScanOpts
753
+ -> m (f (Cursor , [(ByteString , Double )])) -- ^ next cursor and values
754
+ zscanOpts key cursor opts = sendRequest $ addScanOpts [" ZSCAN" , key, encode cursor] opts
0 commit comments