Added generic reply() signal to Request class.

This commit is contained in:
Nathan Osman 2013-07-04 14:14:53 -07:00
parent 45e7ada7dc
commit 1b45cb3777
5 changed files with 57 additions and 21 deletions

View File

@ -63,7 +63,15 @@ namespace QRedis
* @param command the command to execute * @param command the command to execute
* @return an object representing the request * @return an object representing the request
*/ */
Request * sendCommand(const QString & command); Request * sendCommand(const QByteArray & command);
/**
* @brief Attempts to set the specified key to the specified value
* @param name the name of the key
* @param value the value of the key
* @return the request issued
*/
Request * set(const QByteArray & name, const QByteArray & value);
/** /**
* @brief Waits for the socket to finish connecting * @brief Waits for the socket to finish connecting

View File

@ -64,6 +64,11 @@ namespace QRedis
*/ */
void multiBulk(const QVariantList & values); void multiBulk(const QVariantList & values);
/**
* @brief Emitted when any reply is received
*/
void reply();
/** /**
* @brief Emitted when a status reply is received * @brief Emitted when a status reply is received
* @param message a descriptive status message * @param message a descriptive status message

View File

@ -12,12 +12,23 @@ ClientPrivate::ClientPrivate(Client * client)
connect(&socket, &QTcpSocket::readyRead, this, &ClientPrivate::readReply); connect(&socket, &QTcpSocket::readyRead, this, &ClientPrivate::readReply);
} }
int ClientPrivate::readInteger(qlonglong & value)
{
int pos = buffer.indexOf("\r\n");
if(pos != -1)
{
value = buffer.mid(0, pos).toLongLong();
buffer.remove(0, pos + 2);
}
return pos;
}
/* /*
* Note: error replies actually contain a type and then the error description * Note: error replies actually contain a type and then the error description
* but we just combine them here for simplicity. * but we just combine them here for simplicity.
*/ */
bool ClientPrivate::readStatusOrError() bool ClientPrivate::readStatusOrErrorReply()
{ {
/* Check if the reply contains \r\n. */ /* Check if the reply contains \r\n. */
int pos = buffer.indexOf("\r\n"); int pos = buffer.indexOf("\r\n");
@ -37,7 +48,7 @@ bool ClientPrivate::readStatusOrError()
return false; return false;
} }
bool ClientPrivate::readInteger() bool ClientPrivate::readIntegerReply()
{ {
/* Check if the reply contains \r\n. */ /* Check if the reply contains \r\n. */
int pos = buffer.indexOf("\r\n"); int pos = buffer.indexOf("\r\n");
@ -52,7 +63,7 @@ bool ClientPrivate::readInteger()
return false; return false;
} }
bool ClientPrivate::readBulk() bool ClientPrivate::readBulkReply()
{ {
/* Check if the reply contains \r\n. */ /* Check if the reply contains \r\n. */
int pos = buffer.indexOf("\r\n"); int pos = buffer.indexOf("\r\n");
@ -71,7 +82,7 @@ bool ClientPrivate::readBulk()
return false; return false;
} }
bool ClientPrivate::readMultiBulk() bool ClientPrivate::readMultiBulkReply()
{ {
return false; return false;
} }
@ -95,16 +106,16 @@ void ClientPrivate::readReply()
{ {
case '+': case '+':
case '-': case '-':
finished = readStatusOrError(); finished = readStatusOrErrorReply();
break; break;
case ':': case ':':
finished = readInteger(); finished = readIntegerReply();
break; break;
case '$': case '$':
finished = readBulk(); finished = readBulkReply();
break; break;
case '*': case '*':
finished = readMultiBulk(); finished = readMultiBulkReply();
break; break;
} }
@ -137,9 +148,9 @@ bool Client::isConnected() const
return d->socket.state() == QAbstractSocket::ConnectedState; return d->socket.state() == QAbstractSocket::ConnectedState;
} }
Request * Client::sendCommand(const QString & command) Request * Client::sendCommand(const QByteArray & command)
{ {
d->socket.write(QString("%1\r\n").arg(command).toUtf8()); d->socket.write(command + "\r\n");
Request * request = new Request(this); Request * request = new Request(this);
d->queue.enqueue(request); d->queue.enqueue(request);

View File

@ -18,10 +18,13 @@ namespace QRedis
ClientPrivate(Client *); ClientPrivate(Client *);
bool readStatusOrError(); /* Utility methods for reading items from the buffer. */
bool readInteger(); int readInteger(qlonglong &);
bool readBulk();
bool readMultiBulk(); bool readStatusOrErrorReply();
bool readIntegerReply();
bool readBulkReply();
bool readMultiBulkReply();
QTcpSocket socket; QTcpSocket socket;

View File

@ -13,6 +13,19 @@ void RequestPrivate::quitEventLoop()
Request::Request(QObject * parent) Request::Request(QObject * parent)
: QObject(parent), d(new RequestPrivate) : QObject(parent), d(new RequestPrivate)
{ {
/*
* Each of these signals also causes the generic reply() signal to be emitted.
*/
connect(this, SIGNAL(bulk(QByteArray)), SIGNAL(reply()));
connect(this, SIGNAL(error(QString)), SIGNAL(reply()));
connect(this, SIGNAL(integer(qlonglong)), SIGNAL(reply()));
connect(this, SIGNAL(multiBulk(QVariantList)), SIGNAL(reply()));
connect(this, SIGNAL(status(QString)), SIGNAL(reply()));
/*
* We also need to ensure that this object is deleted when the reply is received.
*/
connect(this, SIGNAL(reply()), SLOT(deleteLater()));
} }
Request::~Request() Request::~Request()
@ -25,12 +38,8 @@ bool Request::waitForReply(int msecs)
timer.setInterval(msecs); timer.setInterval(msecs);
timer.setSingleShot(true); timer.setSingleShot(true);
connect(&timer, SIGNAL(timeout()), &d->loop, SLOT(quit())); connect(&timer, SIGNAL(timeout()), &d->loop, SLOT(quit()));
connect(this, SIGNAL(bulk(QByteArray)), d.data(), SLOT(quitEventLoop())); connect(this, SIGNAL(reply()), d.data(), SLOT(quitEventLoop()));
connect(this, SIGNAL(error(QString)), d.data(), SLOT(quitEventLoop()));
connect(this, SIGNAL(integer(qlonglong)), d.data(), SLOT(quitEventLoop()));
connect(this, SIGNAL(multiBulk(QVariantList)), d.data(), SLOT(quitEventLoop()));
connect(this, SIGNAL(status(QString)), d.data(), SLOT(quitEventLoop()));
/* /*
* If the timer fires, the return value will be 0. * If the timer fires, the return value will be 0.