Skip to content

Commit

Permalink
Add query for column_info in sqlite3 backend
Browse files Browse the repository at this point in the history
  • Loading branch information
Sildra committed Oct 12, 2023
1 parent 2e4b44b commit 6f8efb6
Show file tree
Hide file tree
Showing 6 changed files with 271 additions and 57 deletions.
11 changes: 6 additions & 5 deletions include/soci/column-info.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,22 @@ struct type_conversion<column_info>
static std::size_t get_numeric_value(const values & v,
const std::string & field_name)
{
data_type dt = v.get_properties(field_name).get_data_type();
std::size_t pos = v.find_column(field_name);
data_type dt = v.get_properties(pos).get_data_type();
switch (dt)
{
case dt_double:
return static_cast<std::size_t>(
v.get<double>(field_name, 0.0));
v.get<double>(pos, 0.0));
case dt_integer:
return static_cast<std::size_t>(
v.get<int>(field_name, 0));
v.get<int>(pos, 0));
case dt_long_long:
return static_cast<std::size_t>(
v.get<long long>(field_name, 0ll));
v.get<long long>(pos, 0ll));
case dt_unsigned_long_long:
return static_cast<std::size_t>(
v.get<unsigned long long>(field_name, 0ull));
v.get<unsigned long long>(pos, 0ull));
break;
default:
return 0u;
Expand Down
12 changes: 3 additions & 9 deletions include/soci/row.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class SOCI_DECL row
row(row &&other) = default;
row &operator=(row &&other) = default;

std::size_t find_column(std::string const& name) const;

void uppercase_column_names(bool forceToUpper);
void add_properties(column_properties const& cp);
std::size_t size() const;
Expand Down Expand Up @@ -97,13 +99,7 @@ class SOCI_DECL row
T get(std::string const &name, T const &nullValue) const
{
std::size_t const pos = find_column(name);

if (i_null == *indicators_[pos])
{
return nullValue;
}

return get<T>(pos);
return get<T>(pos, nullValue);
}

template <typename T>
Expand All @@ -127,8 +123,6 @@ class SOCI_DECL row
private:
SOCI_NOT_COPYABLE(row)

std::size_t find_column(std::string const& name) const;

std::vector<column_properties> columns_;
std::vector<details::holder*> holders_;
std::vector<indicator*> indicators_;
Expand Down
15 changes: 15 additions & 0 deletions include/soci/sqlite3/soci-sqlite3.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,21 @@ struct sqlite3_session_backend : details::session_backend
return "select name as \"TABLE_NAME\""
" from sqlite_master where type = 'table'";
}
std::string get_column_descriptions_query() const override
{
return "select name as 'COLUMN_NAME',"
" 0 as 'CHARACTER_MAXIMUM_LENGTH',"
" 0 as 'NUMERIC_PRECISION',"
" case when type like '%real%' or type like '%float%' or type like '%double%' then 255 else 0 end as 'NUMERIC_SCALE',"
" case"
" when type like 'text' or type like 'clob' or type like '%char%' then 'text'"
" when type like '%int%' or type like '%number%' or type like '%numeric%' then 'integer'"
" when type like '%real%' or type like '%float%' or type like '%double%' then 'number'"
" else type"
" end as 'DATA_TYPE',"
" case when \"notnull\" = 0 then 'YES' else 'NO' end as 'IS_NULLABLE'"
" from (select name, lower(type) as type, \"notnull\" from pragma_table_info(:t))";
}
std::string create_column_type(data_type dt,
int , int ) override
{
Expand Down
51 changes: 27 additions & 24 deletions include/soci/values.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,25 @@ class SOCI_DECL values

values() : row_(NULL), currentPos_(0), uppercaseColumnNames_(false) {}

std::size_t find_column(std::string const& name) const
{
if (row_ != NULL)
return row_->find_column(name);

const auto pos = index_.find(name);
if (pos != index_.end())
{
return pos->second;
}
throw soci_error("Value named " + name + " not found.");
}

indicator get_indicator(std::size_t pos) const;
indicator get_indicator(std::string const & name) const;
indicator get_indicator(std::string const & name) const
{
std::size_t pos = find_column(name);
return get_indicator(pos);
}

template <typename T>
T get(std::size_t pos) const
Expand Down Expand Up @@ -95,15 +112,17 @@ class SOCI_DECL values
template <typename T>
T get(std::string const & name) const
{
return row_ != NULL ? row_->get<T>(name) : get_from_uses<T>(name);
std::size_t pos = find_column(name);
return row_ != NULL ? row_->get<T>(pos) : get_from_uses<T>(pos);
}

template <typename T>
T get(std::string const & name, T const & nullValue) const
{
std::size_t pos = find_column(name);
return row_ != NULL
? row_->get<T>(name, nullValue)
: get_from_uses<T>(name, nullValue);
? row_->get<T>(pos, nullValue)
: get_from_uses<T>(pos, nullValue);
}

template <typename T>
Expand Down Expand Up @@ -254,30 +273,14 @@ class SOCI_DECL values
// without an underlying row object. In that case, get_from_uses()
// returns the underlying field values
template <typename T>
T get_from_uses(std::string const & name, T const & nullValue) const
T get_from_uses(std::size_t pos, T const & nullValue) const
{
std::map<std::string, std::size_t>::const_iterator pos = index_.find(name);
if (pos != index_.end())
if (*indicators_[pos] == i_null)
{
if (*indicators_[pos->second] == i_null)
{
return nullValue;
}

return get_from_uses<T>(pos->second);
return nullValue;
}
throw soci_error("Value named " + name + " not found.");
}

template <typename T>
T get_from_uses(std::string const & name) const
{
std::map<std::string, std::size_t>::const_iterator pos = index_.find(name);
if (pos != index_.end())
{
return get_from_uses<T>(pos->second);
}
throw soci_error("Value named " + name + " not found.");
return get_from_uses<T>(pos);
}

template <typename T>
Expand Down
19 changes: 0 additions & 19 deletions src/core/values.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,6 @@ indicator values::get_indicator(std::size_t pos) const
}
}

indicator values::get_indicator(std::string const& name) const
{
if (row_)
{
return row_->get_indicator(name);
}
else
{
std::map<std::string, std::size_t>::const_iterator it = index_.find(name);
if (it == index_.end())
{
std::ostringstream msg;
msg << "Column '" << name << "' not found";
throw soci_error(msg.str());
}
return *indicators_[it->second];
}
}

column_properties const& values::get_properties(std::size_t pos) const
{
if (row_)
Expand Down
Loading

0 comments on commit 6f8efb6

Please sign in to comment.