I'm grabbing a row from a database using libpqxx and assigning the fields within the pqxx::row to a struct specifically designed to hold those values:
struct driveOperationRecord
{
long int id = 0;
long int drive_operator_id = 0;
long int operator_operation_index = 0;
long int specific_operation_id = 0;
bool operation_outcome = false;
std::string error_code = "";
long int operation_seconds = 0;
std::string operation_date = "";
std::string serial_number = "";
std::string model = "";
long long int size = 0;
std::string firmware = "";
};
To do this I'm currently using the following code:
void driveOperationEntryToRecord(pqxx::row entry, driveOperationRecord& record)
{
try
{
if (!entry["id"].is_null()) record.id = entry["id"].as<int>();
if (!entry["drive_operator_id"].is_null()) record.drive_operator_id = entry["drive_operator_id"].as<int>();
if (!entry["operator_operation_index"].is_null()) record.operator_operation_index = entry["operator_operation_index"].as<int>();
if (!entry["specific_operation_id"].is_null()) record.specific_operation_id = entry["specific_operation_id"].as<int>();
if (!entry["operation_outcome"].is_null()) record.operation_outcome = entry["operation_outcome"].as<bool>();
if (!entry["error_code"].is_null()) record.error_code = entry["error_code"].as<std::string>();
if (!entry["operation_seconds"].is_null()) record.operation_seconds = entry["operation_seconds"].as<long int>();
if (!entry["operation_date"].is_null()) record.operation_date = entry["operation_date"].as<std::string>();
if (!entry["serial_number"].is_null()) record.serial_number = entry["serial_number"].as<std::string>();
if (!entry["model"].is_null()) record.model = entry["model"].as<std::string>();
if (!entry["size"].is_null()) record.size = entry["size"].as<long long int>();
if (!entry["firmware"].is_null()) record.firmware = entry["firmware"].as<std::string>();
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
Which is absolutely horrible and I hate it. I've thought about using a switch with an appropriate enum but iterating through a switch 12 times feels even worse. Ideally I'd be able to use something like:
for (auto field : entry)
{
if (!field.is_null()) record.<if only i could dynamically reference using field.name()> = field.as<somehow magically find appropriate type>();
}
But these things are impossible. Any ideas?
EDIT (In response to Useless):
The current database contains roughly 4,000 entries which will need to pass through this function on a fairly regular basis. It is expected to grow exponentially from here. In order to future proof, operational efficiency is also important. I am fairly new to c++ and I know that there is a lot that I don't know! I was just really hoping to find something slightly more elegant and have really been struggling to do so.