1//
2// Client.cpp
3//
4// Library: Redis
5// Package: Redis
6// Module: Client
7//
8// Implementation of the Client class.
9//
10// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#include "Poco/Redis/Client.h"
18#include "Poco/Redis/Exception.h"
19
20
21namespace Poco {
22namespace Redis {
23
24
25Client::Client():
26 _address(),
27 _socket(),
28 _input(0),
29 _output(0),
30 _authenticated(false)
31{
32}
33
34
35Client::Client(const std::string& hostAndPort):
36 _address(hostAndPort),
37 _socket(),
38 _input(0),
39 _output(0),
40 _authenticated(false)
41{
42 connect();
43}
44
45
46Client::Client(const std::string& host, int port):
47 _address(host, static_cast<UInt16>(port)),
48 _socket(),
49 _input(0),
50 _output(0),
51 _authenticated(false)
52{
53 connect();
54}
55
56
57Client::Client(const Net::SocketAddress& addrs):
58 _address(addrs),
59 _socket(),
60 _input(0),
61 _output(0),
62 _authenticated(false)
63{
64 connect();
65}
66
67
68Client::~Client()
69{
70 delete _input;
71 delete _output;
72 _socket.close();
73}
74
75
76void Client::connect()
77{
78 poco_assert(! _input);
79 poco_assert(! _output);
80
81 _socket.connect(_address);
82 _input = new RedisInputStream(_socket);
83 _output = new RedisOutputStream(_socket);
84}
85
86
87void Client::connect(const std::string& hostAndPort)
88{
89 _address = Net::SocketAddress(hostAndPort);
90 connect();
91}
92
93
94void Client::connect(const std::string& host, int port)
95{
96 _address = Net::SocketAddress(host, static_cast<UInt16>(port));
97 connect();
98}
99
100
101void Client::connect(const Net::SocketAddress& addrs)
102{
103 _address = addrs;
104 connect();
105}
106
107
108void Client::connect(const Timespan& timeout)
109{
110 poco_assert(! _input);
111 poco_assert(! _output);
112
113 _socket.connect(_address, timeout);
114 _input = new RedisInputStream(_socket);
115 _output = new RedisOutputStream(_socket);
116}
117
118
119void Client::connect(const std::string& hostAndPort, const Timespan& timeout)
120{
121 _address = Net::SocketAddress(hostAndPort);
122 connect(timeout);
123}
124
125
126void Client::connect(const std::string& host, int port, const Timespan& timeout)
127{
128 _address = Net::SocketAddress(host, static_cast<UInt16>(port));
129 connect(timeout);
130}
131
132
133void Client::connect(const Net::SocketAddress& addrs, const Timespan& timeout)
134{
135 _address = addrs;
136 connect(timeout);
137}
138
139
140bool Client::sendAuth(const std::string& password)
141{
142 Array cmd;
143 cmd << "AUTH" << password;
144
145 bool ret = true;
146 std::string response;
147
148 try {
149 response = execute<std::string>(cmd);
150 } catch (...) {
151 ret = false;
152 }
153
154 _authenticated = (ret && (response == "OK"));
155
156 return _authenticated;
157}
158
159
160void Client::disconnect()
161{
162 delete _input;
163 _input = 0;
164
165 delete _output;
166 _output = 0;
167
168 _socket.close();
169}
170
171
172bool Client::isConnected() const
173{
174 return _input != 0;
175}
176
177
178void Client::writeCommand(const Array& command, bool doFlush)
179{
180 poco_assert(_output);
181
182 std::string commandStr = command.toString();
183
184 _output->write(commandStr.c_str(), commandStr.length());
185 if (doFlush) _output->flush();
186}
187
188
189RedisType::Ptr Client::readReply()
190{
191 poco_assert(_input);
192
193 char c = static_cast<char>(_input->get());
194 RedisType::Ptr result = RedisType::createRedisType(c);
195 if (result.isNull())
196 {
197 throw RedisException("Invalid Redis type returned");
198 }
199
200 result->read(*_input);
201
202 return result;
203}
204
205
206RedisType::Ptr Client::sendCommand(const Array& command)
207{
208 writeCommand(command, true);
209 return readReply();
210}
211
212
213Array Client::sendCommands(const std::vector<Array>& commands)
214{
215 Array results;
216
217 for (std::vector<Array>::const_iterator it = commands.begin(); it != commands.end(); ++it)
218 {
219 writeCommand(*it, false);
220 }
221 _output->flush();
222
223 for (int i = 0; i < commands.size(); ++i)
224 {
225 results.addRedisType(readReply());
226 }
227
228 return results;
229}
230
231
232} } // namespace Poco::Redis
233