Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion include/SQLiteCpp/Statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,18 @@ class Statement
*
* Throw an exception if the specified index is out of the [0, getColumnCount()) range.
*/
bool isColumnNull(const int aIndex) const;
bool isColumnNull(const int aIndex);

/**
* @brief Test if the column value is NULL
*
* @param[in] apName Aliased name of the column, that is, the named specified in the query (not the original name)
*
* @return true if the column value is NULL
*
* Throw an exception if the specified name is not an on of the aliased name of the columns in the result.
*/
bool isColumnNull(const char* apName);

/**
* @brief Return a pointer to the named assigned to the specified result column (potentially aliased)
Expand Down
24 changes: 23 additions & 1 deletion src/Statement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,13 +336,35 @@ Column Statement::getColumn(const char* apName)
}

// Test if the column is NULL
bool Statement::isColumnNull(const int aIndex) const
bool Statement::isColumnNull(const int aIndex)
{
checkRow();
checkIndex(aIndex);
return (SQLITE_NULL == sqlite3_column_type(mStmtPtr, aIndex));
}

bool Statement::isColumnNull(const char* apName)
{
checkRow();

if (mColumnNames.empty())
{
for (int i = 0; i < mColumnCount; ++i)
{
const char* pName = sqlite3_column_name(mStmtPtr, i);
mColumnNames[pName] = i;
}
}

const TColumnNames::const_iterator iIndex = mColumnNames.find(apName);
if (iIndex == mColumnNames.end())
{
throw SQLite::Exception("Unknown column name.");
}

return (SQLITE_NULL == sqlite3_column_type(mStmtPtr, (*iIndex).second));
}

// Return the named assigned to the specified result column (potentially aliased)
const char* Statement::getColumnName(const int aIndex) const
{
Expand Down
62 changes: 62 additions & 0 deletions tests/Statement_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,68 @@ TEST(Statement, isColumnNull) {
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
}

TEST(Statement, isColumnNullByName) {
// Create a new database
SQLite::Database db(":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
ASSERT_EQ(SQLITE_OK, db.getErrorCode());

// Create a new table
EXPECT_EQ(0, db.exec("CREATE TABLE test (msg TEXT, int INTEGER, double REAL)"));
ASSERT_EQ(SQLITE_OK, db.getErrorCode());

// Create a first row with no null values, then other rows with each time a NULL value
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", 123, 0.123)"));
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, 123, 0.123)"));
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", NULL, 0.123)"));
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", 123, NULL)"));

// Compile a SQL query
const std::string select("SELECT * FROM test");
SQLite::Statement query(db, select);
EXPECT_EQ(select, query.getQuery());
EXPECT_EQ(3, query.getColumnCount());

// Get the first non-null row
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_THROW(query.isColumnNull(""), SQLite::Exception);
EXPECT_EQ(false, query.isColumnNull("msg"));
EXPECT_EQ(false, query.isColumnNull("int"));
EXPECT_EQ(false, query.isColumnNull("double"));
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);

// Get the second row with null text
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_THROW(query.isColumnNull(""), SQLite::Exception);
EXPECT_EQ(true, query.isColumnNull("msg"));
EXPECT_EQ(false, query.isColumnNull(1));
EXPECT_EQ(false, query.isColumnNull("double"));
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);

// Get the second row with null integer
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_THROW(query.isColumnNull(""), SQLite::Exception);
EXPECT_EQ(false, query.isColumnNull("msg"));
EXPECT_EQ(true, query.isColumnNull("int"));
EXPECT_EQ(false, query.isColumnNull("double"));
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);

// Get the third row with null float
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_THROW(query.isColumnNull(""), SQLite::Exception);
EXPECT_EQ(false, query.isColumnNull("msg"));
EXPECT_EQ(false, query.isColumnNull("int"));
EXPECT_EQ(true, query.isColumnNull("double"));
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
}

TEST(Statement, getColumnByName) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
Expand Down