C++ code formatting

This commit is contained in:
Aaron Po
2026-08-24 01:13:41 -04:00
parent b64c42ebde
commit 03ca966708
12 changed files with 136 additions and 143 deletions

View File

@@ -51,10 +51,9 @@ class HttpWebClient final : public WebClient {
* @param headers Additional request headers. * @param headers Additional request headers.
* @return Response body on HTTP 2xx; throws std::runtime_error otherwise. * @return Response body on HTTP 2xx; throws std::runtime_error otherwise.
*/ */
std::string Post( std::string Post(const std::string& url, const std::string& body,
const std::string& url, const std::string& body, const std::vector<std::pair<std::string, std::string>>&
const std::vector<std::pair<std::string, std::string>>& headers) headers) override;
override;
/** /**
* @brief Percent-encodes a single URI component (query parameter value or * @brief Percent-encodes a single URI component (query parameter value or

View File

@@ -121,9 +121,9 @@ std::optional<ApplicationOptions> ParseArguments(
// Enforce mutual exclusivity before any further configuration is // Enforce mutual exclusivity before any further configuration is
// applied. // applied.
const int selected_generator_count = const int selected_generator_count = (use_mocked ? 1 : 0) +
(use_mocked ? 1 : 0) + (!model_path.empty() ? 1 : 0) + (!model_path.empty() ? 1 : 0) +
(use_openai ? 1 : 0); (use_openai ? 1 : 0);
if (selected_generator_count > 1) { if (selected_generator_count > 1) {
const std::string msg = const std::string msg =
@@ -190,7 +190,8 @@ std::optional<ApplicationOptions> ParseArguments(
: use_openai ? GeneratorMode::kOpenAI : use_openai ? GeneratorMode::kOpenAI
: GeneratorMode::kLlama; : GeneratorMode::kLlama;
options.generator.model_path = model_path; options.generator.model_path = model_path;
options.generator.openai_model = var_map["openai-model"].as<std::string>(); options.generator.openai_model =
var_map["openai-model"].as<std::string>();
// Only populate sampling config when the user explicitly overrides at // Only populate sampling config when the user explicitly overrides at
// least one value. Leaving it as std::nullopt lets LlamaGenerator fall // least one value. Leaving it as std::nullopt lets LlamaGenerator fall

View File

@@ -17,18 +17,18 @@ void BiergartenPipelineOrchestrator::LogResults() const {
for (const auto& [address, brewery] : generated_breweries_) { for (const auto& [address, brewery] : generated_breweries_) {
const City& city = address.city; const City& city = address.city;
brewery_output.push_back(boost::json::object{ brewery_output.push_back(boost::json::object{
{"name_en", brewery.name_en}, {"name_en", brewery.name_en},
{"description_en", brewery.description_en}, {"description_en", brewery.description_en},
{"name_local", brewery.name_local}, {"name_local", brewery.name_local},
{"description_local", brewery.description_local}, {"description_local", brewery.description_local},
{"address", boost::json::object{ {"address", boost::json::object{
{"city", city.city}, {"city", city.city},
{"country", city.country}, {"country", city.country},
{"state_province", city.state_province}, {"state_province", city.state_province},
{"iso3166_2", city.iso3166_2}, {"iso3166_2", city.iso3166_2},
{"longitude", address.longitude}, {"longitude", address.longitude},
{"latitude", address.latitude}, {"latitude", address.latitude},
}}}); }}});
} }
std::ostringstream brewery_oss; std::ostringstream brewery_oss;
@@ -41,14 +41,14 @@ void BiergartenPipelineOrchestrator::LogResults() const {
for (const auto& generated_user : generated_users_) { for (const auto& generated_user : generated_users_) {
user_output.push_back(boost::json::object{ user_output.push_back(boost::json::object{
{"first_name", generated_user.user.first_name}, {"first_name", generated_user.user.first_name},
{"last_name", generated_user.user.last_name}, {"last_name", generated_user.user.last_name},
{"gender", generated_user.user.gender}, {"gender", generated_user.user.gender},
{"username", generated_user.user.username}, {"username", generated_user.user.username},
{"bio", generated_user.user.bio}, {"bio", generated_user.user.bio},
{"activity_weight", generated_user.user.activity_weight}, {"activity_weight", generated_user.user.activity_weight},
{"email", generated_user.email}, {"email", generated_user.email},
{"date_of_birth", generated_user.date_of_birth}, {"date_of_birth", generated_user.date_of_birth},
}); });
} }

View File

@@ -43,6 +43,5 @@ std::vector<City> BiergartenPipelineOrchestrator::QueryLocations() {
" Locations available: {}\n Sampled Locations: {}", " Locations available: {}\n Sampled Locations: {}",
all_locations.size(), sampled_locations.size())}); all_locations.size(), sampled_locations.size())});
return sampled_locations; return sampled_locations;
} }

View File

@@ -8,14 +8,13 @@
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <boost/json.hpp>
#include <cctype> #include <cctype>
#include <format> #include <format>
#include <span> #include <span>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <boost/json.hpp>
namespace { namespace {
std::string Trim(std::string_view value) { std::string Trim(std::string_view value) {
constexpr std::string_view whitespace = " \t\n\r\f\v"; constexpr std::string_view whitespace = " \t\n\r\f\v";
@@ -55,7 +54,8 @@ std::string CondenseWhitespace(std::string_view text) {
return out; return out;
} }
// Keeps truncation past the string's midpoint, preserving the critical opening content. // Keeps truncation past the string's midpoint, preserving the critical opening
// content.
constexpr size_t kTruncationGuardDivisor = 2; constexpr size_t kTruncationGuardDivisor = 2;
bool ReadRequiredTrimmedStringField(const boost::json::object& obj, bool ReadRequiredTrimmedStringField(const boost::json::object& obj,
@@ -64,8 +64,7 @@ bool ReadRequiredTrimmedStringField(const boost::json::object& obj,
const boost::json::value* field = obj.if_contains(key); const boost::json::value* field = obj.if_contains(key);
if (field == nullptr || !field->is_string()) { if (field == nullptr || !field->is_string()) {
if (error_out != nullptr) { if (error_out != nullptr) {
*error_out = *error_out = std::format("Missing or invalid string field: {}", key);
std::format("Missing or invalid string field: {}", key);
} }
return false; return false;
} }

View File

@@ -6,9 +6,11 @@
* *
* API docs last accessed 2026-08-23. * API docs last accessed 2026-08-23.
* Docs: https://platform.openai.com/docs/api-reference/chat/create * Docs: https://platform.openai.com/docs/api-reference/chat/create
* Structured Outputs: https://platform.openai.com/docs/guides/structured-outputs * Structured Outputs:
* https://platform.openai.com/docs/guides/structured-outputs
*/ */
#include <boost/json.hpp>
#include <format> #include <format>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
@@ -16,15 +18,13 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <boost/json.hpp>
#include "data_generation/openai_generator.h" #include "data_generation/openai_generator.h"
namespace { namespace {
// https://platform.openai.com/docs/api-reference/chat/create // https://platform.openai.com/docs/api-reference/chat/create
constexpr std::string_view kChatCompletionsUrl = constexpr std::string_view kChatCompletionsUrl =
"https://api.openai.com/v1/chat/completions"; "https://api.openai.com/v1/chat/completions";
} // namespace } // namespace
/** /**
* @brief Sends a single Chat Completions request constrained by a JSON * @brief Sends a single Chat Completions request constrained by a JSON
@@ -45,22 +45,22 @@ constexpr std::string_view kChatCompletionsUrl =
* response, model refusal, or missing content. * response, model refusal, or missing content.
*/ */
std::string OpenAIGenerator::CallChatCompletionsApi( std::string OpenAIGenerator::CallChatCompletionsApi(
const std::string& system_prompt, const std::string& user_prompt, const std::string& system_prompt, const std::string& user_prompt,
std::string_view json_schema, std::string_view schema_name, std::string_view json_schema, std::string_view schema_name,
int max_tokens) { int max_tokens) {
boost::system::error_code schema_error; boost::system::error_code schema_error;
boost::json::value schema_value = boost::json::value schema_value =
boost::json::parse(json_schema, schema_error); boost::json::parse(json_schema, schema_error);
bool schema_is_invalid = static_cast<bool>(schema_error); bool schema_is_invalid = static_cast<bool>(schema_error);
if (schema_is_invalid) { if (schema_is_invalid) {
throw std::runtime_error( throw std::runtime_error(
"OpenAIGenerator: invalid embedded JSON schema: " + "OpenAIGenerator: invalid embedded JSON schema: " +
schema_error.message()); schema_error.message());
} }
// response_format: https://platform.openai.com/docs/guides/structured-outputs // response_format:
// https://platform.openai.com/docs/guides/structured-outputs
boost::json::object json_schema_wrapper; boost::json::object json_schema_wrapper;
json_schema_wrapper["name"] = std::string(schema_name); json_schema_wrapper["name"] = std::string(schema_name);
json_schema_wrapper["strict"] = true; json_schema_wrapper["strict"] = true;
@@ -91,27 +91,27 @@ std::string OpenAIGenerator::CallChatCompletionsApi(
const std::string body = boost::json::serialize(request); const std::string body = boost::json::serialize(request);
const std::vector<std::pair<std::string, std::string>> headers = { const std::vector<std::pair<std::string, std::string>> headers = {
{"Authorization", std::format("Bearer {}", api_key_)}, {"Authorization", std::format("Bearer {}", api_key_)},
}; };
const std::string response_body = const std::string response_body =
web_client_->Post(std::string(kChatCompletionsUrl), body, headers); web_client_->Post(std::string(kChatCompletionsUrl), body, headers);
boost::system::error_code response_error; boost::system::error_code response_error;
boost::json::value response_value = boost::json::value response_value =
boost::json::parse(response_body, response_error); boost::json::parse(response_body, response_error);
bool response_body_is_invalid = static_cast<bool>(response_error); bool response_body_is_invalid = static_cast<bool>(response_error);
if (response_body_is_invalid) { if (response_body_is_invalid) {
throw std::runtime_error( throw std::runtime_error(
"OpenAIGenerator: failed to parse API response: " + "OpenAIGenerator: failed to parse API response: " +
response_error.message()); response_error.message());
} }
bool response_root_is_not_object = !response_value.is_object(); bool response_root_is_not_object = !response_value.is_object();
if (response_root_is_not_object) { if (response_root_is_not_object) {
throw std::runtime_error( throw std::runtime_error(
"OpenAIGenerator: API response root is not an object"); "OpenAIGenerator: API response root is not an object");
} }
const auto& response_obj = response_value.get_object(); const auto& response_obj = response_value.get_object();
@@ -119,63 +119,63 @@ std::string OpenAIGenerator::CallChatCompletionsApi(
const boost::json::value* error_field = response_obj.if_contains("error"); const boost::json::value* error_field = response_obj.if_contains("error");
bool top_level_error_occurred = bool top_level_error_occurred =
error_field != nullptr && error_field->is_object(); error_field != nullptr && error_field->is_object();
if (top_level_error_occurred) { if (top_level_error_occurred) {
std::string error_message = "unknown error"; std::string error_message = "unknown error";
if (const boost::json::value* message_field = if (const boost::json::value* message_field =
error_field->get_object().if_contains("message"); error_field->get_object().if_contains("message");
message_field != nullptr && message_field->is_string()) { message_field != nullptr && message_field->is_string()) {
error_message = std::string(message_field->as_string()); error_message = std::string(message_field->as_string());
} }
throw std::runtime_error( throw std::runtime_error(std::format(
std::format("OpenAIGenerator: API request failed: {}", error_message)); "OpenAIGenerator: API request failed: {}", error_message));
} }
const boost::json::value* choices_field = response_obj. const boost::json::value* choices_field =
if_contains("choices"); response_obj.if_contains("choices");
bool choices_field_missing_or_invalid = bool choices_field_missing_or_invalid = choices_field == nullptr ||
choices_field == nullptr || !choices_field->is_array() || !choices_field->is_array() ||
choices_field->get_array().empty(); choices_field->get_array().empty();
if (choices_field_missing_or_invalid) { if (choices_field_missing_or_invalid) {
throw std::runtime_error( throw std::runtime_error(
"OpenAIGenerator: API response missing choices array"); "OpenAIGenerator: API response missing choices array");
} }
const boost::json::value& first_choice = choices_field->get_array().front(); const boost::json::value& first_choice = choices_field->get_array().front();
bool first_choice_is_not_object = !first_choice.is_object(); bool first_choice_is_not_object = !first_choice.is_object();
if (first_choice_is_not_object) { if (first_choice_is_not_object) {
throw std::runtime_error( throw std::runtime_error(
"OpenAIGenerator: API response choice is not an object"); "OpenAIGenerator: API response choice is not an object");
} }
const auto& choice_obj = first_choice.get_object(); const auto& choice_obj = first_choice.get_object();
const boost::json::value* message_field = choice_obj.if_contains("message"); const boost::json::value* message_field = choice_obj.if_contains("message");
bool message_field_missing_or_invalid = bool message_field_missing_or_invalid =
message_field == nullptr || !message_field->is_object(); message_field == nullptr || !message_field->is_object();
if (message_field_missing_or_invalid) { if (message_field_missing_or_invalid) {
throw std::runtime_error( throw std::runtime_error(
"OpenAIGenerator: API response choice missing message"); "OpenAIGenerator: API response choice missing message");
} }
const auto& message_obj = message_field->get_object(); const auto& message_obj = message_field->get_object();
// Refusal field: https://platform.openai.com/docs/guides/structured-outputs // Refusal field: https://platform.openai.com/docs/guides/structured-outputs
const boost::json::value* refusal_field = message_obj.if_contains("refusal"); const boost::json::value* refusal_field = message_obj.if_contains("refusal");
bool model_refused_request = bool model_refused_request = refusal_field != nullptr &&
refusal_field != nullptr && refusal_field->is_string() && refusal_field->is_string() &&
!refusal_field->as_string().empty(); !refusal_field->as_string().empty();
if (model_refused_request) { if (model_refused_request) {
throw std::runtime_error(std::format( throw std::runtime_error(
"OpenAIGenerator: request refused by safety policies: {}", std::format("OpenAIGenerator: request refused by safety policies: {}",
std::string(refusal_field->as_string()))); std::string(refusal_field->as_string())));
} }
const boost::json::value* content_field = message_obj.if_contains("content"); const boost::json::value* content_field = message_obj.if_contains("content");
bool content_field_missing_or_invalid = bool content_field_missing_or_invalid =
content_field == nullptr || !content_field->is_string(); content_field == nullptr || !content_field->is_string();
if (content_field_missing_or_invalid) { if (content_field_missing_or_invalid) {
throw std::runtime_error( throw std::runtime_error(
"OpenAIGenerator: API response message had no text content"); "OpenAIGenerator: API response message had no text content");
} }
return std::string(content_field->as_string()); return std::string(content_field->as_string());

View File

@@ -17,8 +17,7 @@
namespace { namespace {
std::string FormatLocalLanguageCodes( std::string FormatLocalLanguageCodes(const std::vector<std::string>& codes) {
const std::vector<std::string>& codes) {
if (codes.empty()) { if (codes.empty()) {
return "Not provided"; return "Not provided";
} }
@@ -36,7 +35,8 @@ std::string FormatLocalLanguageCodes(
constexpr int kBreweryMaxTokens = 2800; constexpr int kBreweryMaxTokens = 2800;
// Structured outputs already guarantee schema-valid JSON, so retries here only cover transient failures or the model returning placeholder text. // Structured outputs already guarantee schema-valid JSON, so retries here only
// cover transient failures or the model returning placeholder text.
constexpr int kMaxAttempts = 2; constexpr int kMaxAttempts = 2;
} // namespace } // namespace
@@ -51,7 +51,8 @@ BreweryResult OpenAIGenerator::GenerateBrewery(
FormatLocalLanguageCodes(location.local_languages); FormatLocalLanguageCodes(location.local_languages);
/** /**
* Loads the backend-agnostic brewery system prompt via the injected prompt directory. * Loads the backend-agnostic brewery system prompt via the injected prompt
* directory.
*/ */
const std::string system_prompt = const std::string system_prompt =
prompt_directory_->Load("BREWERY_GENERATION"); prompt_directory_->Load("BREWERY_GENERATION");
@@ -70,9 +71,9 @@ BreweryResult OpenAIGenerator::GenerateBrewery(
std::string last_error; std::string last_error;
for (int attempt = 0; attempt < kMaxAttempts; ++attempt) { for (int attempt = 0; attempt < kMaxAttempts; ++attempt) {
raw = CallChatCompletionsApi(system_prompt, user_prompt, raw =
kBreweryJsonSchema, "brewery_result", CallChatCompletionsApi(system_prompt, user_prompt, kBreweryJsonSchema,
kBreweryMaxTokens); "brewery_result", kBreweryMaxTokens);
if (logger_) { if (logger_) {
logger_->Log({.level = LogLevel::Debug, logger_->Log({.level = LogLevel::Debug,
.phase = PipelinePhase::BreweryAndBeerGeneration, .phase = PipelinePhase::BreweryAndBeerGeneration,

View File

@@ -16,7 +16,8 @@
namespace { namespace {
constexpr int kUserMaxTokens = 1200; constexpr int kUserMaxTokens = 1200;
// Structured outputs already guarantee schema-valid JSON, so retries here only cover transient failures or placeholder text. // Structured outputs already guarantee schema-valid JSON, so retries here only
// cover transient failures or placeholder text.
constexpr int kMaxAttempts = 2; constexpr int kMaxAttempts = 2;
} // namespace } // namespace
@@ -47,8 +48,7 @@ UserResult OpenAIGenerator::GenerateUser(const EnrichedCity& city,
const std::string retry_context = std::format( const std::string retry_context = std::format(
"Name: {} {}\nCity: {}, {}\nPersona: {}", name.first_name, "Name: {} {}\nCity: {}, {}\nPersona: {}", name.first_name,
name.last_name, city.location.city, city.location.country, name.last_name, city.location.city, city.location.country, persona.name);
persona.name);
std::string raw; std::string raw;
std::string last_error; std::string last_error;

View File

@@ -3,12 +3,12 @@
* @brief OpenAIGenerator constructor. * @brief OpenAIGenerator constructor.
*/ */
#include "data_generation/openai_generator.h"
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility> #include <utility>
#include "data_generation/openai_generator.h"
OpenAIGenerator::OpenAIGenerator( OpenAIGenerator::OpenAIGenerator(
std::string api_key, std::string model, std::shared_ptr<ILogger> logger, std::string api_key, std::string model, std::shared_ptr<ILogger> logger,
std::unique_ptr<IPromptDirectory> prompt_directory, std::unique_ptr<IPromptDirectory> prompt_directory,

View File

@@ -166,54 +166,54 @@ int main(const int argc, char** argv) {
inj.template create<std::unique_ptr<WebClient>>(), inj.template create<std::unique_ptr<WebClient>>(),
log_producer); log_producer);
}), }),
di::bind<DataGenerator>().to( di::bind<DataGenerator>().to([&options, &model_path, &sampling,
[&options, &model_path, &sampling, &prompt_directory, &prompt_directory,
&log_producer]( &log_producer](const auto& inj)
const auto& inj) -> std::unique_ptr<DataGenerator> { -> std::unique_ptr<DataGenerator> {
if (options.generator.mode == GeneratorMode::kMock) { if (options.generator.mode == GeneratorMode::kMock) {
log_producer->Log({.level = LogLevel::Info, log_producer->Log({.level = LogLevel::Info,
.phase = PipelinePhase::Startup, .phase = PipelinePhase::Startup,
.message = "Generator: mock"}); .message = "Generator: mock"});
return std::make_unique<MockGenerator>(); return std::make_unique<MockGenerator>();
} }
if (options.generator.mode == GeneratorMode::kOpenAI) { if (options.generator.mode == GeneratorMode::kOpenAI) {
log_producer->Log( log_producer->Log({.level = LogLevel::Info,
{.level = LogLevel::Info, .phase = PipelinePhase::Startup,
.phase = PipelinePhase::Startup, .message = std::format(
.message = std::format( "Generator: OpenAIGenerator | model={}",
"Generator: OpenAIGenerator | model={}", options.generator.openai_model)});
options.generator.openai_model)});
return std::make_unique<OpenAIGenerator>( return std::make_unique<OpenAIGenerator>(
options.generator.openai_api_key, options.generator.openai_api_key,
options.generator.openai_model, log_producer, options.generator.openai_model, log_producer,
std::move(prompt_directory), std::move(prompt_directory),
inj.template create<std::unique_ptr<WebClient>>()); inj.template create<std::unique_ptr<WebClient>>());
} }
#ifdef BIERGARTEN_MOCK_ONLY #ifdef BIERGARTEN_MOCK_ONLY
// Only reachable when mode == Llama, which requires llama.cpp and is excluded from a BIERGARTEN_MOCK_ONLY build. // Only reachable when mode == Llama, which requires llama.cpp and
throw std::runtime_error( // is excluded from a BIERGARTEN_MOCK_ONLY build.
"LlamaGenerator is unavailable in a BIERGARTEN_MOCK_ONLY " throw std::runtime_error(
"build"); "LlamaGenerator is unavailable in a BIERGARTEN_MOCK_ONLY "
"build");
#else #else
log_producer->Log( log_producer->Log(
{.level = LogLevel::Info, {.level = LogLevel::Info,
.phase = PipelinePhase::Startup, .phase = PipelinePhase::Startup,
.message = std::format( .message = std::format(
"Generator: LlamaGenerator | model={} | " "Generator: LlamaGenerator | model={} | "
"temp={:.2f} top_p={:.2f} top_k={} n_ctx={} seed={}", "temp={:.2f} top_p={:.2f} top_k={} n_ctx={} seed={}",
model_path, sampling.temperature, sampling.top_p, model_path, sampling.temperature, sampling.top_p,
sampling.top_k, sampling.n_ctx, sampling.seed)}); sampling.top_k, sampling.n_ctx, sampling.seed)});
return std::make_unique<LlamaGenerator>( return std::make_unique<LlamaGenerator>(
options, model_path, log_producer, options, model_path, log_producer,
inj.template create<std::unique_ptr<IPromptFormatter>>(), inj.template create<std::unique_ptr<IPromptFormatter>>(),
std::move(prompt_directory)); std::move(prompt_directory));
#endif #endif
})); }));
const auto orchestrator = const auto orchestrator =
injector.create<std::unique_ptr<BiergartenPipelineOrchestrator>>(); injector.create<std::unique_ptr<BiergartenPipelineOrchestrator>>();

View File

@@ -81,7 +81,7 @@ boost::json::value ParseJsonFile(const std::filesystem::path& filepath) {
std::ifstream input(filepath); std::ifstream input(filepath);
if (!input.is_open()) { if (!input.is_open()) {
throw std::runtime_error( throw std::runtime_error(
std::format("Failed to open file: {}", filepath.string())); std::format("Failed to open file: {}", filepath.string()));
} }
std::stringstream buffer; std::stringstream buffer;
@@ -125,8 +125,7 @@ const LocationsList& CuratedJsonDataService::LoadLocations() {
if (!cache_.locations.empty()) { if (!cache_.locations.empty()) {
return cache_.locations; return cache_.locations;
} }
boost::json::value root_val = boost::json::value root_val = ParseJsonFile(filepaths_.locations_path);
ParseJsonFile(filepaths_.locations_path);
if (!root_val.is_object()) { if (!root_val.is_object()) {
throw std::runtime_error( throw std::runtime_error(
@@ -135,14 +134,12 @@ const LocationsList& CuratedJsonDataService::LoadLocations() {
boost::json::object root_obj = root_val.as_object(); boost::json::object root_obj = root_val.as_object();
if (!root_obj.contains("cities")) if (!root_obj.contains("cities")) {
{
throw std::runtime_error( throw std::runtime_error(
"Invalid locations JSON: root object must contain a 'cities' key"); "Invalid locations JSON: root object must contain a 'cities' key");
} }
if (!root_obj["cities"].is_array()) if (!root_obj["cities"].is_array()) {
{
throw std::runtime_error( throw std::runtime_error(
"Invalid locations JSON: 'cities' key must be an array"); "Invalid locations JSON: 'cities' key must be an array");
} }
@@ -179,8 +176,7 @@ const PersonasList& CuratedJsonDataService::LoadPersonas() {
return cache_.personas; return cache_.personas;
} }
const boost::json::value root = const boost::json::value root = ParseJsonFile(filepaths_.personas_path);
ParseJsonFile(filepaths_.personas_path);
if (!root.is_array()) { if (!root.is_array()) {
throw std::runtime_error( throw std::runtime_error(
@@ -215,8 +211,7 @@ const ForenamesByCountryMap& CuratedJsonDataService::LoadForenamesByCountry() {
return cache_.forenames_by_country; return cache_.forenames_by_country;
} }
const boost::json::value root = const boost::json::value root = ParseJsonFile(filepaths_.forenames_path);
ParseJsonFile(filepaths_.forenames_path);
if (!root.is_object()) { if (!root.is_object()) {
throw std::runtime_error( throw std::runtime_error(
@@ -263,8 +258,7 @@ const SurnamesByCountryMap& CuratedJsonDataService::LoadSurnamesByCountry() {
return cache_.surnames_by_country; return cache_.surnames_by_country;
} }
const boost::json::value root = const boost::json::value root = ParseJsonFile(filepaths_.surnames_path);
ParseJsonFile(filepaths_.surnames_path);
if (!root.is_object()) { if (!root.is_object()) {
throw std::runtime_error( throw std::runtime_error(

View File

@@ -180,8 +180,8 @@ uint64_t SqliteExportService::ProcessRecord(const BreweryRecord& brewery) {
sqlite_export_service_internal::Bind( sqlite_export_service_internal::Bind(
insert_brewery_address_stmt_, insert_brewery_address_stmt_,
sqlite_export_service_internal::BoundParam<double>{ sqlite_export_service_internal::BoundParam<double>{
.index = sqlite_export_service_internal:: .index =
kBreweryAddressLatitudeBindIndex, sqlite_export_service_internal::kBreweryAddressLatitudeBindIndex,
.value = brewery.address.latitude, .value = brewery.address.latitude,
.action = "Failed to bind SQLite brewery address latitude"}); .action = "Failed to bind SQLite brewery address latitude"});