Start implementing shared BLOB tests

This commit is contained in:
Robert Adam
2022-09-19 20:15:02 +02:00
parent 62a58ad47f
commit 68033e037a
6 changed files with 203 additions and 1 deletions
+131
View File
@@ -417,6 +417,12 @@ public:
// Returns null by default to indicate that CLOB is not supported.
virtual table_creator_base* table_creator_clob(session&) const { return NULL; }
// Override this to return the table creator for a simple table containing
// an integer "id" column and BLOB "b" one.
//
// Returns null by default to indicate that BLOB is not supported.
virtual table_creator_base* table_creator_blob(session&) const { return NULL; }
// Override this to return the table creator for a simple table containing
// an integer "id" column and XML "x" one.
//
@@ -6364,6 +6370,131 @@ TEST_CASE_METHOD(common_tests, "Into XML vector with several fetches", "[core][x
REQUIRE(!st.fetch());
}
TEST_CASE_METHOD(common_tests, "BLOB", "[core][blob]")
{
soci::session sql(backEndFactory_, connectString_);
auto_table_creator tableCreator(tc_.table_creator_blob(sql));
if (!tableCreator.get())
{
try
{
soci::blob blob(sql);
FAIL("BLOB creation should throw, if backend doesn't support BLOBs");
} catch (const soci_error &)
{
// Throwing is expected if the backend doesn't support BLOBs
}
WARN("BLOB type not supported by the database, skipping the test.");
return;
}
const char dummy_data[] = "abcdefghijklmnopüqrstuvwxyz";
// Cross-DB usage of BLOBs is only possible if the entire lifetime of the blob object
// is covered in an active transaction.
soci::transaction transaction(sql);
{
SECTION("Read-access on default-constructed blob")
{
soci::blob blob(sql);
CHECK(blob.get_len() == 0);
char buf[5];
std::size_t read_bytes = blob.read_from_start(buf, sizeof(buf));
// There should be no data that could be read
CHECK(read_bytes == 0);
// Reading from any offset other than zero is invalid
CHECK_THROWS_AS(blob.read_from_start(buf, sizeof(buf), 1), soci_error);
}
SECTION("Write-access on default-constructed blob")
{
soci::blob blob(sql);
std::size_t written_bytes = blob.write_from_start(dummy_data, 5);
CHECK(written_bytes == 5);
CHECK(blob.get_len() == 5);
char buf[5];
std::size_t read_bytes = blob.read_from_start(buf, sizeof(buf));
CHECK(read_bytes == 5);
for (std::size_t i = 0; i < sizeof(buf); ++i)
{
CHECK(buf[i] == dummy_data[i]);
}
written_bytes = blob.append(dummy_data + 5, 3);
CHECK(written_bytes == 3);
CHECK(blob.get_len() == 8);
read_bytes = blob.read_from_start(buf, sizeof(buf), 3);
CHECK(read_bytes == 5);
for (std::size_t i = 0; i < sizeof(buf); ++i)
{
CHECK(buf[i] == dummy_data[i + 3]);
}
blob.trim(2);
CHECK(blob.get_len() == 2);
read_bytes = blob.read_from_start(buf, sizeof(buf));
CHECK(read_bytes == 2);
for (std::size_t i = 0; i < read_bytes; ++i)
{
CHECK(buf[i] == dummy_data[i]);
}
// Reading from an offset >= the current length of the blob is invalid
CHECK_THROWS_AS(blob.read_from_start(buf, sizeof(buf), blob.get_len()), soci_error);
written_bytes = blob.append("z", 1);
CHECK(written_bytes == 1);
CHECK(blob.get_len() == 3);
read_bytes = blob.read_from_start(buf, 1, 2);
CHECK(read_bytes == 1);
CHECK(buf[0] == 'z');
// Writing more than one position beyond the blob is invalid
// (Writing exactly one position beyond is the same as appending)
CHECK_THROWS_AS(blob.write_from_start(dummy_data, 2, blob.get_len() + 1), soci_error);
}
SECTION("Inserting default-constructed blob into DB")
{
soci::blob blob(sql);
sql << "insert into soci_test (id, b) values(5, :b)", soci::use(blob);
}
SECTION("Fetching default-constructed blob from DB")
{
soci::blob blob(sql);
soci::indicator ind;
sql << "select b from soci_test where id = 5", soci::into(blob, ind);
CHECK(ind == soci::i_ok);
CHECK(blob.get_len() == 0);
}
}
transaction.rollback();
}
TEST_CASE_METHOD(common_tests, "Logger", "[core][log]")
{
// Logger class used for testing: appends all queries to the provided
+15
View File
@@ -1307,6 +1307,15 @@ struct TableCreatorCLOB : public tests::table_creator_base
}
};
struct TableCreatorBLOB : public tests::table_creator_base
{
TableCreatorBLOB(soci::session & sql)
: tests::table_creator_base(sql)
{
sql << "create table soci_test(id integer, b blob)";
}
};
struct TableCreatorXML : public tests::table_creator_base
{
TableCreatorXML(soci::session & sql)
@@ -1351,6 +1360,12 @@ class test_context : public tests::test_context_base
return new TableCreatorCLOB(s);
}
tests::table_creator_base* table_creator_blob(soci::session& s) const override
{
return new TableCreatorBLOB(s);
}
tests::table_creator_base* table_creator_xml(soci::session& s) const override
{
return new TableCreatorXML(s);
+15
View File
@@ -49,6 +49,16 @@ struct table_creator_for_get_affected_rows : table_creator_base
}
};
struct table_creator_for_blob : public tests::table_creator_base
{
table_creator_for_blob(soci::session & sql)
: tests::table_creator_base(sql)
{
sql << "create table soci_test(id integer, b blob)";
}
};
//
// Support for SOCI Common Tests
//
@@ -85,6 +95,11 @@ public:
return "\'" + datdt_string + "\'";
}
table_creator_base* table_creator_blob(soci::session& s) const override
{
return new table_creator_for_blob(s);
}
bool has_fp_bug() const override
{
// MySQL fails in the common test3() with "1.8000000000000000 !=
+13
View File
@@ -1480,6 +1480,14 @@ struct table_creator_for_clob : table_creator_base
}
};
struct table_creator_for_blob : public tests::table_creator_base
{
table_creator_for_blob(soci::session &sql) : tests::table_creator_base(sql)
{
sql << "create table soci_test(id integer, b blob)";
}
};
class test_context :public test_context_base
{
public:
@@ -1512,6 +1520,11 @@ public:
return new table_creator_for_clob(s);
}
table_creator_base* table_creator_blob(soci::session& s) const override
{
return new table_creator_for_blob(s);
}
table_creator_base* table_creator_xml(soci::session& s) const override
{
return new table_creator_for_xml(s);
+15 -1
View File
@@ -1433,7 +1433,16 @@ struct table_creator_for_clob : table_creator_base
}
};
// Common tests context
struct table_creator_for_blob : public tests::table_creator_base
{
table_creator_for_blob(soci::session & sql)
: tests::table_creator_base(sql)
{
sql << "create table soci_test(id integer, b oid)";
}
};
class test_context : public test_context_base
{
public:
@@ -1471,6 +1480,11 @@ public:
return new table_creator_for_clob(s);
}
table_creator_base* table_creator_blob(soci::session& s) const override
{
return new table_creator_for_blob(s);
}
bool has_real_xml_support() const override
{
return true;
+14
View File
@@ -898,6 +898,15 @@ struct table_creator_from_str : table_creator_base
}
};
struct table_creator_for_blob : public tests::table_creator_base
{
table_creator_for_blob(soci::session & sql)
: tests::table_creator_base(sql)
{
sql << "create table soci_test(id integer, b blob)";
}
};
class test_context : public test_context_base
{
public:
@@ -931,6 +940,11 @@ public:
"create table soci_test (id integer primary key, val integer)");
}
table_creator_base* table_creator_blob(soci::session& s) const override
{
return new table_creator_for_blob(s);
}
table_creator_base* table_creator_xml(soci::session& s) const override
{
return new table_creator_from_str(s,