예제 #1
0
        public async Task <Result <bool> > Exists(ISession session, string key)
        {
            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.EXISTS)
                    .WithKey(key)
                    .ToString();

                var result = await SendCommandAndReadResponseAsync(session, command);

                var parsed = int.TryParse(result[0]?.ToString(), out var resultInt);

                if (parsed)
                {
                    switch (resultInt)
                    {
                    case 0:
                        return(Result.Ok(false));

                    case 1:
                        return(Result.Ok(true));

                    default:
                        return(Result.Fail <bool>($"Exists expected 0 or 1, got {resultInt}"));
                    }
                }

                return(Result.Fail <bool>($"Could not parse the returned value '{result[0]}' to integer"));
            }
            catch (Exception ex)
            {
                return(Result.Fail <bool>(ex.Message, ex));
            }
        }
예제 #2
0
        public async Task <Result> Unsubscribe(ISession session, IEnumerable <string> channels)
        {
            try
            {
                var chs = channels.ToList();

                var command =
                    new BasicCommandBuilder(RedisCommands.UNSUBSCRIBE)
                    .WithParameters(chs)
                    .ToString();

                await SendCommandAsync(session, command);

                var isUnsubOk = true;
                foreach (var ch in chs)
                {
                    isUnsubOk &= _unsubEvent.WaitOne(TimeSpan.FromSeconds(3));
                }

                return(isUnsubOk ? Result.Ok() : Result.Fail("Timeout expired before unsubscribe notification was received"));
            }
            catch (Exception ex)
            {
                return(Result.Fail(ex.Message, ex));
            }
        }
예제 #3
0
        public async Task <Result <IDictionary <string, string> > > HGetAll(ISession session, string key)
        {
            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.HGETALL)
                    .WithKey(key)
                    .ToString();

                var result = await SendCommandAndReadResponseAsync(session, command);

                if (result.Length % 2 == 1)
                {
                    Result.Fail <IDictionary <string, string> >($"Received an odd number of items: [{string.Join(", ", result.Select(i => i?.ToString()))}]");
                }

                IDictionary <string, string> d = new Dictionary <string, string>();
                for (var i = 0; i < result.Length; i += 2)
                {
                    d[result[i].ToString()] = result[i + 1].ToString();
                }

                return(Result.Ok(d));
            }
            catch (Exception ex)
            {
                return(Result.Fail <IDictionary <string, string> >(ex.Message, ex));
            }
        }
예제 #4
0
        public async Task <Result <IEnumerable <string> > > HMGet(ISession session, string key, IEnumerable <string> fields)
        {
            try
            {
                var f = fields.ToArray();

                var command =
                    new BasicCommandBuilder(RedisCommands.HMGET)
                    .WithKey(key)
                    .WithParameters(f)
                    .ToString();

                var result = await SendCommandAndReadResponseAsync(session, command);

                var stringResult = result.Select(i => i?.ToString()).ToArray();

                if (result.Length != f.Length)
                {
                    Result.Fail <IDictionary <string, string> >($"Received {result.Length} items instead of {f.Length}: [{string.Join(", ", stringResult)}]");
                }

                return(Result.Ok(stringResult.AsEnumerable()));
            }
            catch (Exception ex)
            {
                return(Result.Fail <IEnumerable <string> >(ex.Message, ex));
            }
        }
예제 #5
0
        public async Task <Result <object[]> > Exec(ISession session)
        {
            try
            {
                var command = new BasicCommandBuilder(RedisCommands.EXEC).ToString();

                var result = await SendCommandAndReadResponseAsync(session, command);

                return(result == null
                    ? Result.Fail <object[]>(RedisConstants.TransactionAborted)
                    : Result.Ok(result));
            }
            catch (Exception ex)
            {
                return(Result.Fail <object[]>(ex.Message, ex));
            }
        }
예제 #6
0
        public async Task <Result> Ping(ISession session)
        {
            try
            {
                var command = new BasicCommandBuilder(RedisCommands.PING).ToString();

                var response = await SendCommandAndReadResponseAsync(session, command);

                var responseString = response[0]?.ToString();

                return(IsResponsePong(responseString) ? Result.Ok() : Result.Fail(responseString));
            }
            catch (Exception ex)
            {
                return(Result.Fail(ex.Message, ex));
            }
        }
예제 #7
0
        private async Task <Result> Auth(ISession session, string secret)
        {
            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.AUTH)
                    .WithKey(secret)
                    .ToString();

                var resultCode = await SendCommandAndReadResponseAsync(session, command);

                return(string.Equals(resultCode[0].ToString(), RedisConstants.OkResult) ? Result.Ok() : Result.Fail(resultCode[0].ToString()));
            }
            catch (Exception ex)
            {
                return(Result.Fail(ex.Message, ex));
            }
        }
예제 #8
0
        public async Task <Result <string> > Get(ISession session, string key)
        {
            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.GET)
                    .WithKey(key)
                    .ToString();

                var result = await SendCommandAndReadResponseAsync(session, command);

                return(Result.Ok(result[0]?.ToString()));
            }
            catch (Exception ex)
            {
                return(Result.Fail <string>(ex.Message, ex));
            }
        }
예제 #9
0
        public async Task <Result <List <string> > > SMembers(ISession session, string key)
        {
            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.SMEMBERS)
                    .WithKey(key)
                    .ToString();

                var result = await SendCommandAndReadResponseAsync(session, command);

                return(Result.Ok(result.Select(i => i.ToString()).ToList()));
            }
            catch (Exception ex)
            {
                return(Result.Fail <List <string> >(ex.Message, ex));
            }
        }
예제 #10
0
        public async Task <Result> SwapDb(ISession session, int index1, int index2)
        {
            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.SWAPDB)
                    .WithParameter(index1)
                    .WithParameter(index2)
                    .ToString();

                var response = await SendCommandAndReadResponseAsync(session, command);

                return(IsResponseOk(response[0]) ? Result.Ok() : Result.Fail(response[0]?.ToString()));
            }
            catch (Exception ex)
            {
                return(Result.Fail(ex.Message, ex));
            }
        }
예제 #11
0
        public async Task <Result> Discard(ISession session)
        {
            try
            {
                var command = new BasicCommandBuilder(RedisCommands.DISCARD).ToString();

                var response = await SendCommandAndReadResponseAsync(session, command);

                var responseString = response[0]?.ToString();

                return(string.Equals(responseString, RedisConstants.OkResult)
                    ? Result.Ok()
                    : Result.Fail(responseString));
            }
            catch (Exception ex)
            {
                return(Result.Fail(ex.Message, ex));
            }
        }
예제 #12
0
        public async Task <Result <long> > DbSize(ISession session)
        {
            try
            {
                var command = new BasicCommandBuilder(RedisCommands.DBSIZE).ToString();

                var response = await SendCommandAndReadResponseAsync(session, command);

                var responseString = response[0]?.ToString();

                var isOk = long.TryParse(responseString, out var result);
                return(isOk
                    ? Result.Ok(result)
                    : Result.Fail <long>(responseString));
            }
            catch (Exception ex)
            {
                return(Result.Fail <long>(ex.Message, ex));
            }
        }
예제 #13
0
        public async Task <Result> FlushDb(ISession session, bool async)
        {
            try
            {
                var commandBuilder = new BasicCommandBuilder(RedisCommands.FLUSHDB);
                if (async)
                {
                    commandBuilder.WithParameter(RedisConstants.Async);
                }
                var command = commandBuilder.ToString();

                var response = await SendCommandAndReadResponseAsync(session, command);

                return(IsResponseOk(response[0]) ? Result.Ok() : Result.Fail(response[0]?.ToString()));
            }
            catch (Exception ex)
            {
                return(Result.Fail(ex.Message, ex));
            }
        }
예제 #14
0
        public async Task <Result <object[]> > ExecuteScript(ISession session, string sha, string[] parameters)
        {
            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.EVALSHA)
                    .WithKey(sha)
                    .WithParameter(0)
                    .WithParameters(parameters)
                    .ToString();

                var res = await SendCommandAndReadResponseAsync(session, command);

                return(Result.Ok(res));
            }
            catch (Exception ex)
            {
                return(Result.Fail <object[]>(ex.Message, ex));
            }
        }
예제 #15
0
        public async Task <Result <List <string> > > LRange(ISession session, string key, int start, int stop)
        {
            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.LRANGE)
                    .WithKey(key)
                    .WithParameter(start)
                    .WithParameter(stop)
                    .ToString();

                var result = await SendCommandAndReadResponseAsync(session, command);

                return(Result.Ok(result.Select(i => i.ToString()).ToList()));
            }
            catch (Exception ex)
            {
                return(Result.Fail <List <string> >(ex.Message, ex));
            }
        }
예제 #16
0
        public async Task <Result> Set(ISession session, string key, string value)
        {
            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.SET)
                    .WithKey(key)
                    .WithParameter(value)
                    .ToString();

                var response = await SendCommandAndReadResponseAsync(session, command);

                var responseString = response[0]?.ToString();

                return(IsResponseOk(responseString) ? Result.Ok() : Result.Fail(responseString));
            }
            catch (Exception ex)
            {
                return(Result.Fail(ex.Message, ex));
            }
        }
예제 #17
0
        public async Task <Result> Publish(ISession session, string channel, string message)
        {
            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.PUBLISH)
                    .WithKey(channel)
                    .WithParameter(message)
                    .ToString();

                var response = await SendCommandAndReadResponseAsync(session, command);

                var responseString = response[0]?.ToString();

                return(int.TryParse(responseString, out _) ? Result.Ok() : Result.Fail(responseString));
            }
            catch (Exception ex)
            {
                return(Result.Fail(ex.Message, ex));
            }
        }
예제 #18
0
        public async Task <Result <string> > LoadScript(ISession session, string script)
        {
            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.SCRIPT_LOAD)
                    .WithParameter(script)
                    .ToString();

                var response = await SendCommandAndReadResponseAsync(session, command);

                var responseString = response[0]?.ToString();

                return(responseString?.Length == ShaLength && !responseString.Contains(" ")
                    ? Result.Ok(responseString)
                    : Result.Fail <string>(responseString));
            }
            catch (Exception ex)
            {
                return(Result.Fail <string>(ex.Message, ex));
            }
        }
예제 #19
0
        public async Task <Result> Watch(ISession session, IEnumerable <string> keys)
        {
            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.WATCH)
                    .WithParameters(keys)
                    .ToString();

                var response = await SendCommandAndReadResponseAsync(session, command);

                var responseString = response[0]?.ToString();

                return(string.Equals(responseString, RedisConstants.OkResult)
                    ? Result.Ok()
                    : Result.Fail(responseString));
            }
            catch (Exception ex)
            {
                return(Result.Fail(ex.Message, ex));
            }
        }
예제 #20
0
        public async Task <Result> HMSet(ISession session, string key, IDictionary <string, string> fieldValues)
        {
            try
            {
                var parameters = fieldValues.SelectMany(kvp => new [] { kvp.Key, kvp.Value }).ToArray();

                var command =
                    new BasicCommandBuilder(RedisCommands.HMSET)
                    .WithKey(key)
                    .WithParameters(parameters)
                    .ToString();

                var response = await SendCommandAndReadResponseAsync(session, command);

                var responseString = response[0]?.ToString();

                return(IsResponseOk(responseString) ? Result.Ok() : Result.Fail(responseString));
            }
            catch (Exception ex)
            {
                return(Result.Fail(ex.Message, ex));
            }
        }
예제 #21
0
        public async Task <Result> Del(ISession session, string key)
        {
            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.DEL)
                    .WithKey(key)
                    .ToString();

                var response = await SendCommandAndReadResponseAsync(session, command);

                var responseString = response[0]?.ToString();

                return(int.TryParse(responseString, out _) ||
                       string.Equals(responseString, RedisConstants.QueuedResult)
                    ? Result.Ok()
                    : Result.Fail(responseString));
            }
            catch (Exception ex)
            {
                return(Result.Fail(ex.Message, ex));
            }
        }
예제 #22
0
        public async Task <Result> Select(ISession session, int dbIndex)
        {
            if (dbIndex < 0 || dbIndex > 15)
            {
                return(Result.Fail("The DB index must be between 0 and 15 (given: {dbIndex})"));
            }

            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.SELECT)
                    .WithParameter(dbIndex)
                    .ToString();

                var response = await SendCommandAndReadResponseAsync(session, command);

                return(IsResponseOk(response[0]) ? Result.Ok() : Result.Fail(response[0]?.ToString()));
            }
            catch (Exception ex)
            {
                return(Result.Fail(ex.Message, ex));
            }
        }
예제 #23
0
        public async Task <Result <bool> > SIsMember(ISession session, string key, string member)
        {
            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.SISMEMBER)
                    .WithKey(key)
                    .WithParameter(member)
                    .ToString();

                var response = await SendCommandAndReadResponseAsync(session, command);

                var responseString = response[0]?.ToString();

                var isOk = int.TryParse(responseString, out var result);
                return(isOk
                    ? Result.Ok(result == 1)
                    : Result.Fail <bool>(responseString));
            }
            catch (Exception ex)
            {
                return(Result.Fail <bool>(ex.Message, ex));
            }
        }
예제 #24
0
        public async Task <Result <long> > SRem(ISession session, string key, params string[] members)
        {
            try
            {
                var command =
                    new BasicCommandBuilder(RedisCommands.SREM)
                    .WithKey(key)
                    .WithParameters(members)
                    .ToString();

                var response = await SendCommandAndReadResponseAsync(session, command);

                var responseString = response[0]?.ToString();

                var isOk = long.TryParse(responseString, out var result);
                return(isOk
                    ? Result.Ok(result)
                    : Result.Fail <long>(responseString));
            }
            catch (Exception ex)
            {
                return(Result.Fail <long>(ex.Message, ex));
            }
        }
예제 #25
0
        public async Task <Result> Subscribe(ISession session, IEnumerable <string> channels)
        {
            try
            {
                var chs = channels.ToList();

                var command =
                    new BasicCommandBuilder(RedisCommands.SUBSCRIBE)
                    .WithParameters(chs)
                    .ToString();

                session.Locker?.Obtain();
                await SendCommandAsync(session, command);

                var      isSubscriptionOk   = true;
                string[] subscriptionResult = { "empty" };

                foreach (var ch in chs)
                {
                    subscriptionResult = (await ParseToEndAsync(session)).Select(i => i.ToString()).ToArray();

                    isSubscriptionOk &= string.Equals(subscriptionResult[0], "subscribe") &&
                                        string.Equals(subscriptionResult[1], ch) &&
                                        int.TryParse(subscriptionResult[2], out _);
                }

                if (!isSubscriptionOk)
                {
                    session.Locker?.Release();
                    return(Result.Fail(subscriptionResult[0]));
                }

                session.SetInfiniteReadTimeout();

                _ = Task.Run(async() =>
                {
                    while (session.IsOpen)
                    {
                        var channelsHash = new HashSet <string>(chs);

                        object[] received;

                        try
                        {
                            received = await ParseToEndAsync(session);
                        }
                        catch (IOException)
                        {
                            // Client might be closed while waiting to receive subscription message.
                            // In this case the loop will exit at the next iteration.
                            continue;
                        }

                        var type = received[0].ToString();

                        var isMessageOk = string.Equals(type, "message") &&
                                          channelsHash.Contains(received[1].ToString());

                        if (!isMessageOk)
                        {
                            if (string.Equals(type, "unsubscribe"))
                            {
                                _unsubEvent.Set();
                            }

                            continue;
                        }

                        OnMessageReceived?.Invoke(received[1].ToString(), received[2].ToString());
                    }
                    session.Locker?.Release();
                }).ConfigureAwait(false);

                return(Result.Ok());
            }
            catch (Exception ex)
            {
                session.Locker?.Release();
                return(Result.Fail(ex.Message, ex));
            }
        }