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, 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, 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, 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
172void Client::writeCommand(const Array& command, bool doFlush)
173{
174 poco_assert(_output);
175
176 std::string commandStr = command.toString();
177
178 _output->write(commandStr.c_str(), commandStr.length());
179 if (doFlush) _output->flush();
180}
181
182
183RedisType::Ptr Client::readReply()
184{
185 poco_assert(_input);
186
187 int c = _input->get();
188 RedisType::Ptr result = RedisType::createRedisType(c);
189 if (result.isNull())
190 {
191 throw RedisException("Invalid Redis type returned");
192 }
193
194 result->read(*_input);
195
196 return result;
197}
198
199
200RedisType::Ptr Client::sendCommand(const Array& command)
201{
202 writeCommand(command, true);
203 return readReply();
204}
205
206
207Array Client::sendCommands(const std::vector<Array>& commands)
208{
209 Array results;
210
211 for (std::vector<Array>::const_iterator it = commands.begin(); it != commands.end(); ++it)
212 {
213 writeCommand(*it, false);
214 }
215 _output->flush();
216
217 for (int i = 0; i < commands.size(); ++i)
218 {
219 results.addRedisType(readReply());
220 }
221
222 return results;
223}
224
225
226} } // namespace Poco::Redis
227