mirror of
https://github.com/SOCI/soci.git
synced 2026-05-12 14:49:13 -05:00
Move roundtrip-tests related helpers to SQLite3 test
This is the only place where they're used so far and it doesn't make sense to compile them many times over when building the tests for the other backends. If these helpers are needed in the other backends tests, we should extract them into their own header and include it as necessary.
This commit is contained in:
@@ -293,131 +293,9 @@ template<> struct type_conversion<PhonebookEntry3>
|
||||
namespace soci
|
||||
{
|
||||
|
||||
// Helper used by test_roundtrip() below which collects all round trip test
|
||||
// data and allows to define a type conversion for it.
|
||||
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;
|
||||
};
|
||||
|
||||
// Test a rountrip insertion data to the current database for the arithmetic type T
|
||||
// This test specifically use the dynamic bindings and the DDL creation statements.
|
||||
template<typename T>
|
||||
struct type_conversion<Roundtrip<T>>
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "Roundtrip currently supported only for numeric types");
|
||||
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();
|
||||
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: FAIL_CHECK("Unsupported type mapped to db_type"); break;
|
||||
}
|
||||
}
|
||||
static void to_base(Roundtrip<T> const &t, soci::values &v, soci::indicator&)
|
||||
{
|
||||
v.set("VAL", t.inVal);
|
||||
}
|
||||
};
|
||||
|
||||
namespace tests
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
void check(soci::Roundtrip<T> const &val)
|
||||
{
|
||||
CHECK(val.inType == val.outType);
|
||||
CHECK(val.inVal == val.outVal);
|
||||
}
|
||||
|
||||
template<>
|
||||
void check(soci::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, soci::db_type inputType, T inputVal)
|
||||
{
|
||||
try
|
||||
{
|
||||
Roundtrip<T> tester(inputType, inputVal);
|
||||
|
||||
const std::string table = "TEST_ROUNDTRIP";
|
||||
sql.create_table(table).column("VAL", tester.inType);
|
||||
struct table_dropper
|
||||
{
|
||||
table_dropper(soci::session& sql, std::string const& table)
|
||||
: sql_(sql), table_(table) {}
|
||||
~table_dropper() { sql_ << "DROP TABLE " << table_; }
|
||||
|
||||
soci::session& sql_;
|
||||
const std::string table_;
|
||||
} dropper(sql, table);
|
||||
|
||||
sql << "INSERT INTO " << table << "(VAL) VALUES (:VAL)", soci::use(const_cast<const Roundtrip<T>&>(tester));
|
||||
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)
|
||||
{
|
||||
FAIL_CHECK(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: improve cleanup capabilities by subtypes, soci_test name may be omitted --mloskot
|
||||
// i.e. optional ctor param accepting custom table name
|
||||
class table_creator_base
|
||||
{
|
||||
public:
|
||||
table_creator_base(session& sql)
|
||||
: msession(sql) { drop(); }
|
||||
|
||||
virtual ~table_creator_base() { drop();}
|
||||
private:
|
||||
void drop()
|
||||
{
|
||||
try
|
||||
{
|
||||
msession << "drop table soci_test";
|
||||
}
|
||||
catch (soci_error const& e)
|
||||
{
|
||||
//std::cerr << e.what() << std::endl;
|
||||
e.what();
|
||||
}
|
||||
}
|
||||
session& msession;
|
||||
|
||||
SOCI_NOT_COPYABLE(table_creator_base)
|
||||
};
|
||||
|
||||
class procedure_creator_base
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -589,6 +589,108 @@ TEST_CASE("SQLite DDL with metadata", "[sqlite][ddl]")
|
||||
CHECK(ddl_t3_found == false);
|
||||
}
|
||||
|
||||
|
||||
// Helpers for the DDL roundtrip test below.
|
||||
namespace soci
|
||||
{
|
||||
|
||||
// Helper used by test_roundtrip() below which collects all round trip test
|
||||
// data and allows to define a type conversion for it.
|
||||
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;
|
||||
};
|
||||
|
||||
// Test a rountrip insertion data to the current database for the arithmetic type T
|
||||
// This test specifically use the dynamic bindings and the DDL creation statements.
|
||||
template<typename T>
|
||||
struct type_conversion<Roundtrip<T>>
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "Roundtrip currently supported only for numeric types");
|
||||
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();
|
||||
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: FAIL_CHECK("Unsupported type mapped to db_type"); break;
|
||||
}
|
||||
}
|
||||
static void to_base(Roundtrip<T> const &t, soci::values &v, soci::indicator&)
|
||||
{
|
||||
v.set("VAL", t.inVal);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void check(soci::Roundtrip<T> const &val)
|
||||
{
|
||||
CHECK(val.inType == val.outType);
|
||||
CHECK(val.inVal == val.outVal);
|
||||
}
|
||||
|
||||
template<>
|
||||
void check(soci::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, soci::db_type inputType, T inputVal)
|
||||
{
|
||||
try
|
||||
{
|
||||
Roundtrip<T> tester(inputType, inputVal);
|
||||
|
||||
const std::string table = "TEST_ROUNDTRIP";
|
||||
sql.create_table(table).column("VAL", tester.inType);
|
||||
struct table_dropper
|
||||
{
|
||||
table_dropper(soci::session& sql, std::string const& table)
|
||||
: sql_(sql), table_(table) {}
|
||||
~table_dropper() { sql_ << "DROP TABLE " << table_; }
|
||||
|
||||
soci::session& sql_;
|
||||
const std::string table_;
|
||||
} dropper(sql, table);
|
||||
|
||||
sql << "INSERT INTO " << table << "(VAL) VALUES (:VAL)", soci::use(const_cast<const Roundtrip<T>&>(tester));
|
||||
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)
|
||||
{
|
||||
FAIL_CHECK(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace soci
|
||||
|
||||
TEST_CASE("SQLite DDL roundrip", "[sqlite][ddl][roundtrip]")
|
||||
{
|
||||
soci::session sql(backEnd, connectString);
|
||||
|
||||
Reference in New Issue
Block a user