Finally squashed the bug in the cell exists() function in libQtCassandra

The libQtCassandra library has had a bug that would create a cell when testing for its existance. This has been very annoying because I had to use a different mechanism to check whether a cell exists instead of calling the simple and effective QCassandraRow::exists() function.

The function would call the table function necessary to read the content of a cell in the Cassandra cluster. The function returns true or false. If false, the data was not retrieved and thus the cell does not exist. However, the row function was not testing the result and a couple lines below it would do a setValue() which had the very bad side effect of creating the cell in a read-only function!

bool QCassandraRow::exists(const QByteArray& column_key) const
{
    if(f_table == NULL) {
        throw std::runtime_error("row was dropped and is not attached to a table anymore");
    }
    QCassandraCells::const_iterator ci(f_cells.find(column_key));
    if(ci != f_cells.end()) {
        // exists in the cache already
        return true;
    }

    // try reading this cell
    QCassandraValue value;
    try {
        // BEFORE
        f_table->getValue(f_key, column_key, value);
        // NOW
        if(!f_table->getValue(f_key, column_key, value)) {
            return false;
        }
    }
    catch(const org::apache::cassandra::NotFoundException&) {
        // it doesn't exist in Cassandra either
        return false;
    }

    QSharedPointer<QCassandraCell> c(const_cast<QCassandraRow *>(this)->cell(column_key));
    c->setValue(value);

    return true;
}

The fact is that the QCassandraContext::getValue() function does the catch() that we have in this function too. When the exception get caught, that context function returns false. By testing that result in the row function, we now can return false as if the exception had propagated.

And as you can see, just before the last return statement we have a c->setValue(value) call which was creating missing values in the exists() function!

As a result I created version 0.5.0. The jump in the version is because I tested against version 2.0.1 of Cassandra and it works great against that version too. It should still work against older version as there were no major changes in the interface since 1.1.5.

Syndicate content

Snap! Websites
An Open Source CMS System in C++

Contact Us Directly