Skip to content

getColumns() does not allow reading null values #521

@ungive

Description

@ungive

First of all, thank you for this great library! It works really well.

I'm trying to use Statement::getColumns<T, N> to populate an intermediary struct with simple fields for each column:

struct TableColumns {
    const char *text;
};

For brevity, my table has a single column text TEXT NULL and I'm selecting with SELECT text FROM table WHERE id = ?;.

Then I run this code to extract all column values:

TableColumns columns = query.getColumns<TableColumns, 1>();

When the text column contains NULL the text field in TableColumns will contain "". This is due to the following code:

const char* getText(const char* apDefaultValue = "") const noexcept;

For some reason getText returns "" by default instead of a nullptr. I understand that this change was made because of #17, but there is no mention why "" is the default instead of nullptr. To me it would make much more sense to return null by default here, since that is what is stored in the database, not "".

This change now unfortunately has the negative effect that it's impossible to get the real value with the getColumns method.

I only see two solutions:

  1. Revert the change and make nullptr the default. This would be a breaking change and would require a major version update.
  2. Implement an "Optional" type that can represent null values while still providing safe access (which is what the default of "" meant to solve, I believe). Add an operator for each type wrapped in "Optional" to Columns.h, then we can define structs with it:
struct TableColumns {
    SQLite::Optional<const char *> text;
    SQLite::Optional<std::string> text;
};

Why a custom Optional type? std::optional doesn't work here (I tried) and it's only available in C++17 and above.

Additional cases to consider might be nullable integers and such, I haven't tested around with that yet though.

What are your thoughts on this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions