zio.redis.api.Sets.scala Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2021 John A. De Goes and the ZIO contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package zio.redis.api
import zio._
import zio.redis.Input._
import zio.redis.Output._
import zio.redis.ResultBuilder._
import zio.redis._
import zio.redis.internal.{RedisCommand, RedisEnvironment}
import zio.schema.Schema
trait Sets[G[+_]] extends RedisEnvironment[G] {
import Sets._
/**
* Add one or more members to a set.
*
* @param key
* Key of set to add to
* @param member
* first member to add
* @param members
* subsequent members to add
* @return
* Returns the number of elements that were added to the set, not including all the elements already present into
* the set.
*/
final def sAdd[K: Schema, M: Schema](key: K, member: M, members: M*): G[Long] = {
val command =
RedisCommand(SAdd, Tuple2(ArbitraryKeyInput[K](), NonEmptyList(ArbitraryValueInput[M]())), LongOutput)
command.run((key, (member, members.toList)))
}
/**
* Get the number of members in a set.
*
* @param key
* Key of set to get the number of members of
* @return
* Returns the cardinality (number of elements) of the set, or 0 if key does not exist.
*/
final def sCard[K: Schema](key: K): G[Long] = {
val command = RedisCommand(SCard, ArbitraryKeyInput[K](), LongOutput)
command.run(key)
}
/**
* Subtract multiple sets.
*
* @param key
* Key of the set to subtract from
* @param keys
* Keys of the sets to subtract
* @return
* Returns the members of the set resulting from the difference between the first set and all the successive sets.
*/
final def sDiff[K: Schema](key: K, keys: K*): ResultBuilder1[Chunk, G] =
new ResultBuilder1[Chunk, G] {
def returning[R: Schema]: G[Chunk[R]] =
RedisCommand(SDiff, NonEmptyList(ArbitraryKeyInput[K]()), ChunkOutput(ArbitraryOutput[R]()))
.run((key, keys.toList))
}
/**
* Subtract multiple sets and store the resulting set in a key.
*
* @param destination
* Key of set to store the resulting set
* @param key
* Key of set to be subtracted from
* @param keys
* Keys of sets to subtract
* @return
* Returns the number of elements in the resulting set.
*/
final def sDiffStore[D: Schema, K: Schema](destination: D, key: K, keys: K*): G[Long] = {
val command = RedisCommand(
SDiffStore,
Tuple2(ArbitraryValueInput[D](), NonEmptyList(ArbitraryKeyInput[K]())),
LongOutput
)
command.run((destination, (key, keys.toList)))
}
/**
* Intersect multiple sets and store the resulting set in a key.
*
* @param destination
* Key of set to store the resulting set
* @param keys
* Keys of the sets to intersect with each other
* @return
* Returns the members of the set resulting from the intersection of all the given sets.
*/
final def sInter[K: Schema](destination: K, keys: K*): ResultBuilder1[Chunk, G] =
new ResultBuilder1[Chunk, G] {
def returning[R: Schema]: G[Chunk[R]] =
RedisCommand(SInter, NonEmptyList(ArbitraryKeyInput[K]()), ChunkOutput(ArbitraryOutput[R]()))
.run((destination, keys.toList))
}
/**
* Intersect multiple sets and store the resulting set in a key.
*
* @param destination
* Key of set to store the resulting set
* @param key
* Key of first set to intersect
* @param keys
* Keys of subsequent sets to intersect
* @return
* Returns the number of elements in the resulting set.
*/
final def sInterStore[D: Schema, K: Schema](
destination: D,
key: K,
keys: K*
): G[Long] = {
val command = RedisCommand(
SInterStore,
Tuple2(ArbitraryValueInput[D](), NonEmptyList(ArbitraryKeyInput[K]())),
LongOutput
)
command.run((destination, (key, keys.toList)))
}
/**
* Determine if a given value is a member of a set.
*
* @param key
* of the set
* @param member
* value which should be searched in the set
* @return
* Returns 1 if the element is a member of the set. 0 if the element is not a member of the set, or if key does not
* exist.
*/
final def sIsMember[K: Schema, M: Schema](key: K, member: M): G[Boolean] = {
val command =
RedisCommand(SIsMember, Tuple2(ArbitraryKeyInput[K](), ArbitraryValueInput[M]()), BoolOutput)
command.run((key, member))
}
/**
* Get all the members in a set.
*
* @param key
* Key of the set to get the members of
* @return
* Returns the members of the set.
*/
final def sMembers[K: Schema](key: K): ResultBuilder1[Chunk, G] =
new ResultBuilder1[Chunk, G] {
def returning[R: Schema]: G[Chunk[R]] =
RedisCommand(SMembers, ArbitraryKeyInput[K](), ChunkOutput(ArbitraryOutput[R]())).run(key)
}
/**
* Move a member from one set to another.
*
* @param source
* Key of the set to move the member from
* @param destination
* Key of the set to move the member to
* @param member
* Element to move
* @return
* Returns 1 if the element was moved. 0 if it was not found.
*/
final def sMove[S: Schema, D: Schema, M: Schema](
source: S,
destination: D,
member: M
): G[Boolean] = {
val command = RedisCommand(
SMove,
Tuple3(ArbitraryValueInput[S](), ArbitraryValueInput[D](), ArbitraryValueInput[M]()),
BoolOutput
)
command.run((source, destination, member))
}
/**
* Remove and return one or multiple random members from a set.
*
* @param key
* Key of the set to remove items from
* @param count
* Number of elements to remove
* @return
* Returns the elements removed.
*/
final def sPop[K: Schema](key: K, count: Option[Long] = None): ResultBuilder1[Chunk, G] =
new ResultBuilder1[Chunk, G] {
def returning[R: Schema]: G[Chunk[R]] = {
val command = RedisCommand(
SPop,
Tuple2(ArbitraryKeyInput[K](), OptionalInput(LongInput)),
MultiStringChunkOutput(ArbitraryOutput[R]())
)
command.run((key, count))
}
}
/**
* Get one or multiple random members from a set.
*
* @param key
* Key of the set to get members from
* @param count
* Number of elements to randomly get
* @return
* Returns the random members.
*/
final def sRandMember[K: Schema](key: K, count: Option[Long] = None): ResultBuilder1[Chunk, G] =
new ResultBuilder1[Chunk, G] {
def returning[R: Schema]: G[Chunk[R]] = {
val command = RedisCommand(
SRandMember,
Tuple2(ArbitraryKeyInput[K](), OptionalInput(LongInput)),
MultiStringChunkOutput(ArbitraryOutput[R]())
)
command.run((key, count))
}
}
/**
* Remove one of more members from a set.
*
* @param key
* Key of the set to remove members from
* @param member
* Value of the first element to remove
* @param members
* Subsequent values of elements to remove
* @return
* Returns the number of members that were removed from the set, not including non existing members.
*/
final def sRem[K: Schema, M: Schema](key: K, member: M, members: M*): G[Long] = {
val command =
RedisCommand(SRem, Tuple2(ArbitraryKeyInput[K](), NonEmptyList(ArbitraryValueInput[M]())), LongOutput)
command.run((key, (member, members.toList)))
}
/**
* Incrementally iterate Set elements.
*
* This is a cursor based scan of an entire set. Call initially with cursor set to 0 and on subsequent calls pass the
* return value as the next cursor.
*
* @param key
* Key of the set to scan
* @param cursor
* Cursor to use for this iteration of scan
* @param pattern
* Glob-style pattern that filters which elements are returned
* @param count
* Count of elements. Roughly this number will be returned by Redis if possible
* @return
* Returns the next cursor, and items for this iteration or nothing when you reach the end, as a tuple.
*/
final def sScan[K: Schema](
key: K,
cursor: Long,
pattern: Option[String] = None,
count: Option[Count] = None
): ResultBuilder1[({ type lambda[x] = (Long, Chunk[x]) })#lambda, G] =
new ResultBuilder1[({ type lambda[x] = (Long, Chunk[x]) })#lambda, G] {
def returning[R: Schema]: G[(Long, Chunk[R])] = {
val command = RedisCommand(
SScan,
Tuple4(ArbitraryKeyInput[K](), LongInput, OptionalInput(PatternInput), OptionalInput(CountInput)),
Tuple2Output(MultiStringOutput.map(_.toLong), ChunkOutput(ArbitraryOutput[R]()))
)
command.run((key, cursor, pattern.map(Pattern(_)), count))
}
}
/**
* Add multiple sets.
*
* @param key
* Key of the first set to add
* @param keys
* Keys of the subsequent sets to add
* @return
* Returns a list with members of the resulting set.
*/
final def sUnion[K: Schema](key: K, keys: K*): ResultBuilder1[Chunk, G] =
new ResultBuilder1[Chunk, G] {
def returning[R: Schema]: G[Chunk[R]] =
RedisCommand(SUnion, NonEmptyList(ArbitraryKeyInput[K]()), ChunkOutput(ArbitraryOutput[R]()))
.run((key, keys.toList))
}
/**
* Add multiple sets and add the resulting set in a key.
*
* @param destination
* Key of destination to store the result
* @param key
* Key of first set to add
* @param keys
* Subsequent keys of sets to add
* @return
* Returns the number of elements in the resulting set.
*/
final def sUnionStore[D: Schema, K: Schema](
destination: D,
key: K,
keys: K*
): G[Long] = {
val command = RedisCommand(
SUnionStore,
Tuple2(ArbitraryValueInput[D](), NonEmptyList(ArbitraryKeyInput[K]())),
LongOutput
)
command.run((destination, (key, keys.toList)))
}
}
private[redis] object Sets {
final val SAdd = "SADD"
final val SCard = "SCARD"
final val SDiff = "SDIFF"
final val SDiffStore = "SDIFFSTORE"
final val SInter = "SINTER"
final val SInterStore = "SINTERSTORE"
final val SIsMember = "SISMEMBER"
final val SMembers = "SMEMBERS"
final val SMove = "SMOVE"
final val SPop = "SPOP"
final val SRandMember = "SRANDMEMBER"
final val SRem = "SREM"
final val SScan = "SSCAN"
final val SUnion = "SUNION"
final val SUnionStore = "SUNIONSTORE"
}