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
* @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

View File

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

View File

@ -12,12 +12,23 @@ ClientPrivate::ClientPrivate(Client * client)
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
* but we just combine them here for simplicity.
*/
bool ClientPrivate::readStatusOrError()
bool ClientPrivate::readStatusOrErrorReply()
{
/* Check if the reply contains \r\n. */
int pos = buffer.indexOf("\r\n");
@ -37,7 +48,7 @@ bool ClientPrivate::readStatusOrError()
return false;
}
bool ClientPrivate::readInteger()
bool ClientPrivate::readIntegerReply()
{
/* Check if the reply contains \r\n. */
int pos = buffer.indexOf("\r\n");
@ -52,7 +63,7 @@ bool ClientPrivate::readInteger()
return false;
}
bool ClientPrivate::readBulk()
bool ClientPrivate::readBulkReply()
{
/* Check if the reply contains \r\n. */
int pos = buffer.indexOf("\r\n");
@ -71,7 +82,7 @@ bool ClientPrivate::readBulk()
return false;
}
bool ClientPrivate::readMultiBulk()
bool ClientPrivate::readMultiBulkReply()
{
return false;
}
@ -95,16 +106,16 @@ void ClientPrivate::readReply()
{
case '+':
case '-':
finished = readStatusOrError();
finished = readStatusOrErrorReply();
break;
case ':':
finished = readInteger();
finished = readIntegerReply();
break;
case '$':
finished = readBulk();
finished = readBulkReply();
break;
case '*':
finished = readMultiBulk();
finished = readMultiBulkReply();
break;
}
@ -137,9 +148,9 @@ bool Client::isConnected() const
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);
d->queue.enqueue(request);

View File

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

View File

@ -13,6 +13,19 @@ void RequestPrivate::quitEventLoop()
Request::Request(QObject * parent)
: 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()
@ -25,12 +38,8 @@ bool Request::waitForReply(int msecs)
timer.setInterval(msecs);
timer.setSingleShot(true);
connect(&timer, SIGNAL(timeout()), &d->loop, SLOT(quit()));
connect(this, SIGNAL(bulk(QByteArray)), 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()));
connect(&timer, SIGNAL(timeout()), &d->loop, SLOT(quit()));
connect(this, SIGNAL(reply()), d.data(), SLOT(quitEventLoop()));
/*
* If the timer fires, the return value will be 0.