Skip to content

Commit

Permalink
SQLite update DDL creation to the new db enum
Browse files Browse the repository at this point in the history
  • Loading branch information
Sildra committed Jan 17, 2024
1 parent 8ddddca commit 94c1828
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 4 deletions.
10 changes: 9 additions & 1 deletion include/soci/sqlite3/soci-sqlite3.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,15 +345,23 @@ struct sqlite3_session_backend : details::session_backend
case db_double:
return "real";
case db_date:
return "integer";
case db_int8:
return "tinyint";
case db_uint8:
return "unsignedtinyint";
case db_int16:
return "smallint";
case db_uint16:
return "unsignedsmallint";
case db_int32:
return "integer";
case db_uint32:
return "unsignedint";
case db_int64:
return "bigint";
case db_uint64:
return "integer";
return "unsignedbigint";
case db_blob:
return "blob";
default:
Expand Down
10 changes: 7 additions & 3 deletions src/backends/sqlite3/statement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -470,18 +470,22 @@ static sqlite3_data_type_map get_data_type_map()
// integer types
m["tinyint"] = db_int8;

m["unsignedtinyint"] = db_uint8;

m["smallint"] = db_int16;

m["unsignedsmallint"] = db_uint16;

m["boolean"] = db_int32;
m["int"] = db_int32;
m["integer"] = db_int32;
m["int2"] = db_int32;
m["mediumint"] = db_int32;

m["unsignedint"] = db_uint32;

m["bigint"] = db_int64;
m["int8"] = db_int64;

m["unsignedbigint"] = db_uint64;
m["unsignedbigint"] = db_uint64;

// db_string
m["char"] = db_string;
Expand Down
92 changes: 92 additions & 0 deletions tests/common-tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,9 +287,101 @@ template<> struct type_conversion<PhonebookEntry3>
ind = i_ok;
}
};
} // namespace soci

template<typename T>
struct Roundtrip {
typedef T val_type;
Roundtrip(soci::db_type type, T val)
: inType(type), inVal(val) {}

soci::db_type inType;
T inVal;

soci::db_type outType;
T outVal;
};

template<typename T>
void map_roundtrip(soci::values const &v, Roundtrip<T> &t)
{
static_assert(std::is_arithmetic<T>::value, "type T not supported (defaulted to arithmetic types)");
switch (t.outType)
{
case soci::db_int8: t.outVal = static_cast<T>(v.get<std::int8_t>(0)); break;
case soci::db_uint8: t.outVal = static_cast<T>(v.get<std::uint8_t>(0)); break;
case soci::db_int16: t.outVal = static_cast<T>(v.get<std::int16_t>(0)); break;
case soci::db_uint16: t.outVal = static_cast<T>(v.get<std::uint16_t>(0)); break;
case soci::db_int32: t.outVal = static_cast<T>(v.get<std::int32_t>(0)); break;
case soci::db_uint32: t.outVal = static_cast<T>(v.get<std::uint32_t>(0)); break;
case soci::db_int64: t.outVal = static_cast<T>(v.get<std::int64_t>(0)); break;
case soci::db_uint64: t.outVal = static_cast<T>(v.get<std::uint64_t>(0)); break;
case soci::db_double: t.outVal = static_cast<T>(v.get<double>(0)); break;
default: CHECK_FALSE("Unsupported type mapped to db_type"); break;
}
}

template<>
void map_roundtrip(soci::values const &, Roundtrip<std::string> &)
{
CHECK_FALSE("Not yet implemented");
}

namespace soci {
template<typename T>
struct type_conversion<Roundtrip<T>>
{
typedef soci::values base_type;
static void from_base(soci::values const &v, soci::indicator, Roundtrip<T> &t)
{
t.outType = v.get_properties(0).get_db_type();
map_roundtrip(v, t);
}
static void to_base(Roundtrip<T> const &t, soci::values &v, soci::indicator&)
{
v.set("VAL", t.inVal);
}
};
} // namespace soci

template<typename T>
void check(Roundtrip<T> const &val)
{
CHECK(val.inType == val.outType);
CHECK(val.inVal == val.outVal);
}

template<>
void check(Roundtrip<double> const &val)
{
CHECK(val.inType == val.outType);
CHECK(std::fpclassify(val.inVal) == std::fpclassify(val.outVal));
if (std::isnormal(val.inVal) && std::isnormal(val.outVal))
CHECK_THAT(val.inVal, Catch::Matchers::WithinRel(val.outVal));
}

template<typename T>
void test_roundtrip(soci::session &sql, Roundtrip<T>&& tester)
{
const std::string table = "TEST_ROUNDTRIP";
try
{
sql.create_table(table).column("VAL", tester.inType);
sql << "INSERT INTO " << table << "(VAL) VALUES (:VAL)", soci::use(tester.inVal);
soci::statement stmt = (sql.prepare << "SELECT * FROM " << table);
stmt.exchange(soci::into(tester));
stmt.define_and_bind();
stmt.execute();
stmt.fetch();
check(tester);
}
catch (const std::exception& e)
{
CHECK_FALSE(e.what());
}
sql << "DROP TABLE " << table;
}

namespace soci
{
namespace tests
Expand Down
14 changes: 14 additions & 0 deletions tests/sqlite3/test-sqlite3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,20 @@ TEST_CASE("SQLite DDL with metadata", "[sqlite][ddl]")
CHECK(ddl_t3_found == false);
}

TEST_CASE("SQLite DDL roundrip", "[sqlite][ddl][roundtrip]")
{
soci::session sql(backEnd, connectString);
test_roundtrip(sql, Roundtrip<double> (soci::db_double, std::numeric_limits<double>::max()));
test_roundtrip(sql, Roundtrip<std::int8_t> (soci::db_int8, std::numeric_limits<std::int8_t>::max()));
test_roundtrip(sql, Roundtrip<std::int16_t> (soci::db_int16, std::numeric_limits<std::int16_t>::max()));
test_roundtrip(sql, Roundtrip<std::int32_t> (soci::db_int32, std::numeric_limits<std::int32_t>::max()));
test_roundtrip(sql, Roundtrip<std::int64_t> (soci::db_int64, std::numeric_limits<std::int64_t>::max()));
test_roundtrip(sql, Roundtrip<std::uint8_t> (soci::db_uint8, std::numeric_limits<std::uint8_t>::max()));
test_roundtrip(sql, Roundtrip<std::uint16_t>(soci::db_uint16, std::numeric_limits<std::uint16_t>::max()));
test_roundtrip(sql, Roundtrip<std::uint32_t>(soci::db_uint32, std::numeric_limits<std::uint32_t>::max()));
test_roundtrip(sql, Roundtrip<std::uint64_t>(soci::db_uint64, std::numeric_limits<std::uint64_t>::max()));
}

TEST_CASE("SQLite vector long long", "[sqlite][vector][longlong]")
{
soci::session sql(backEnd, connectString);
Expand Down

0 comments on commit 94c1828

Please sign in to comment.