#include "sqlite_result_reader.hpp" #include #include #include namespace matador::backends::sqlite { template < class Type > void read(Type &x, const char *val, typename std::enable_if::value && std::is_signed::value>::type* = nullptr) { if (strlen(val) == 0) { return; } char *end; x = static_cast(strtoll(val, &end, 10)); if (end == nullptr) { // Todo: check error throw std::logic_error("couldn't convert value to number"); } } template < class Type > void read(Type &x, const char *val, typename std::enable_if::value && std::is_unsigned::value>::type* = nullptr) { if (strlen(val) == 0) { return; } char *end; x = static_cast(strtoull(val, &end, 10)); if (end == nullptr) { // Todo: check error throw std::logic_error("couldn't convert value to number"); } } template < class Type > void read(Type &x, const char *val, typename std::enable_if::value>::type* = nullptr) { if (strlen(val) == 0) { return; } char *end; x = static_cast(strtold(val, &end)); if (end == nullptr) { // Todo: check error throw std::logic_error("couldn't convert value to number"); } } sqlite_result_reader::sqlite_result_reader(sqlite_result_reader::rows result, size_t column_count) : result_(std::move(result)) , column_count_(column_count) {} sqlite_result_reader::~sqlite_result_reader() { std::for_each(result_.begin(), result_.end(), [](rows ::value_type& row) { std::for_each(row.begin(), row.end(), [](const char *val) { delete [] val; }); }); } size_t sqlite_result_reader::column_count() const { return column_count_; } const char* sqlite_result_reader::column(size_t index) const { return result_[row_index_][index]; } bool sqlite_result_reader::fetch() { return ++row_index_ < result_.size(); } void sqlite_result_reader::read_value(const char *id, size_t index, char &value) { read(value, result_[row_index_][index]); } void sqlite_result_reader::read_value(const char *id, size_t index, short &value) { read(value, result_[row_index_][index]); } void sqlite_result_reader::read_value(const char *id, size_t index, int &value) { read(value, result_[row_index_][index]); } void sqlite_result_reader::read_value(const char *id, size_t index, long &value) { read(value, result_[row_index_][index]); } void sqlite_result_reader::read_value(const char *id, size_t index, long long int &value) { read(value, result_[row_index_][index]); } void sqlite_result_reader::read_value(const char *id, size_t index, unsigned char &value) { read(value, result_[row_index_][index]); } void sqlite_result_reader::read_value(const char *id, size_t index, unsigned short &value) { read(value, result_[row_index_][index]); } void sqlite_result_reader::read_value(const char *id, size_t index, unsigned int &value) { read(value, result_[row_index_][index]); } void sqlite_result_reader::read_value(const char *id, size_t index, unsigned long &value) { read(value, result_[row_index_][index]); } void sqlite_result_reader::read_value(const char *id, size_t index, unsigned long long int &value) { read(value, result_[row_index_][index]); } void sqlite_result_reader::read_value(const char *id, size_t index, bool &value) { read(value, result_[row_index_][index]); } void sqlite_result_reader::read_value(const char *id, size_t index, float &value) { read(value, result_[row_index_][index]); } void sqlite_result_reader::read_value(const char *id, size_t index, double &value) { read(value, result_[row_index_][index]); } void sqlite_result_reader::read_value(const char *id, size_t index, char *value, size_t size) { auto val = result_[row_index_][index]; size_t len = strlen(val); if (len > size) { #ifdef _MSC_VER strncpy_s(value, size, val, len); #else strncpy(value, val, size); #endif value[size-1] = '\n'; } else { #ifdef _MSC_VER strcpy_s(value, size, val); #else strcpy(value, val); #endif } } void sqlite_result_reader::read_value(const char *id, size_t index, std::string &value) { value.assign(result_[row_index_][index]); } void sqlite_result_reader::read_value(const char *id, size_t index, std::string &value, size_t s) { value.assign(result_[row_index_][index]); } template < typename Type > void convert(const char *valstr, sql::any_type &value) { Type val{}; read(val, valstr); value = val; } void sqlite_result_reader::read_value(const char *id, size_t index, sql::any_type &value, sql::data_type_t type, size_t size) { switch (type) { case sql::data_type_t::type_char: convert(result_[row_index_][index], value); break; case sql::data_type_t::type_short: convert(result_[row_index_][index], value); break; case sql::data_type_t::type_int: convert(result_[row_index_][index], value); break; case sql::data_type_t::type_long: convert(result_[row_index_][index], value); break; case sql::data_type_t::type_long_long: convert(result_[row_index_][index], value); break; case sql::data_type_t::type_unsigned_char: convert(result_[row_index_][index], value); break; case sql::data_type_t::type_unsigned_short: convert(result_[row_index_][index], value); break; case sql::data_type_t::type_unsigned_int: convert(result_[row_index_][index], value); break; case sql::data_type_t::type_unsigned_long: convert(result_[row_index_][index], value); break; case sql::data_type_t::type_unsigned_long_long: convert(result_[row_index_][index], value); break; case sql::data_type_t::type_float: convert(result_[row_index_][index], value); break; case sql::data_type_t::type_double: convert(result_[row_index_][index], value); break; case sql::data_type_t::type_bool: { int val{}; read(val, result_[row_index_][index]); value = val > 0; break; } case sql::data_type_t::type_text: case sql::data_type_t::type_varchar: { value = std::string{result_[row_index_][index]}; break; } case sql::data_type_t::type_char_pointer: { value = result_[row_index_][index]; break; } case sql::data_type_t::type_time: case sql::data_type_t::type_date: { value = std::string{result_[row_index_][index]}; break; } case sql::data_type_t::type_null: { value = nullptr_t{}; break; } case sql::data_type_t::type_blob: { throw std::logic_error("data type blob not supported"); } case sql::data_type_t::type_unknown: { value = std::string(result_[row_index_][index]); break; } } } }