<commit_before>/**
 * @file radon.cpp
 *
 */

#include "radon.h"
#include "logger.h"
#include "plugin_factory.h"
#include "point_list.h"
#include "util.h"
#include <sstream>
#include <thread>

using namespace std;
using namespace himan::plugin;

const int MAX_WORKERS = 32;
static once_flag oflag;
static map<string, string> tableNameCache;
static mutex tableNameMutex;

void radon::Init()
{
	if (!itsInit)
	{
		string radonHost = "vorlon";

		try
		{
			radonHost = util::GetEnv("RADON_HOSTNAME");
		}
		catch (...)
		{
		}

		string radonName = "radon";

		try
		{
			radonName = util::GetEnv("RADON_DATABASENAME");
		}
		catch (...)
		{
		}

		try
		{
			call_once(oflag, [&]() {
				NFmiRadonDBPool::Instance()->Username("wetodb");
				NFmiRadonDBPool::Instance()->Password(util::GetEnv("RADON_WETODB_PASSWORD"));
				NFmiRadonDBPool::Instance()->Database(radonName);
				NFmiRadonDBPool::Instance()->Hostname(radonHost);

				if (NFmiRadonDBPool::Instance()->MaxWorkers() < MAX_WORKERS)
				{
					NFmiRadonDBPool::Instance()->MaxWorkers(MAX_WORKERS);
				}
				itsLogger.Info("Connected to radon (db=" + radonName + ", host=" + radonHost + ")");
			});

			itsRadonDB = std::unique_ptr<NFmiRadonDB>(NFmiRadonDBPool::Instance()->GetConnection());
		}
		catch (int e)
		{
			itsLogger.Fatal("Failed to get connection");
			himan::Abort();
		}

		itsInit = true;
	}
}

radon::radon() : itsInit(false), itsRadonDB()
{
	itsLogger = logger("radon");
}
void radon::PoolMaxWorkers(int maxWorkers)
{
	NFmiRadonDBPool::Instance()->MaxWorkers(maxWorkers);
}
vector<std::string> radon::CSV(search_options& options)
{
	Init();

	vector<string> csv;

	if (options.prod.Class() != kPreviClass)
	{
		itsLogger.Error("Grid producer does not have csv based data");
		return csv;
	}

	stringstream query;

	const auto analtime = options.time.OriginDateTime().String();
	const auto key = to_string(options.prod.Id()) + "_" + analtime;
	string tableName;

	const auto mapValue = tableNameCache.find(key);

	if (mapValue == tableNameCache.end())
	{
		query << "SELECT table_name FROM as_previ WHERE producer_id = " << options.prod.Id()
		      << " AND (min_analysis_time, max_analysis_time) OVERLAPS ('" << analtime << "', '" << analtime << "')";

		itsRadonDB->Query(query.str());

		const auto row = itsRadonDB->FetchRow();

		if (row.empty())
		{
			itsLogger.Error("No tables found from as_previ for producer " + options.prod.Name());
			return csv;
		}

		tableName = row[0];

		lock_guard<mutex> lock(tableNameMutex);
		tableNameCache[key] = tableName;
	}
	else
	{
		tableName = (*mapValue).second;
	}

	string levelValue2 = "-1";

	if (!IsKHPMissingValue(options.level.Value2()))
	{
		levelValue2 = boost::lexical_cast<string>(options.level.Value2());
	}

	const string period = util::MakeSQLInterval(options.time);

	query.str("");

	query << "SELECT "
	      << "t.station_id,"
	      << "s.name AS station_name,"
	      << "st_x(s.position) AS longitude,"
	      << "st_y(s.position) AS latitude,"
	      << "t.value "
	      << "FROM " << tableName << " t, station s "
	      << "WHERE "
	      << "t.station_id = s.id "
	      << "AND t.analysis_time = '" << analtime << "' "
	      << "AND t.param_id = " << options.param.Id() << " "
	      << "AND t.level_id = " << options.level.Type() << " "
	      << "AND t.level_value = " << options.level.Value() << " "
	      << "AND (t.level_value2 = " << options.level.Value2() << " OR t.level_value2 = -1) "
	      << "AND t.forecast_period = '" << period << "' "
	      << "AND t.forecast_type_id = " << options.ftype.Type() << " "
	      << "AND t.forecast_type_value = " << options.ftype.Value() << " "
	      << "AND t.station_id IN (";

	const point_list* list = dynamic_cast<const point_list*>(options.configuration->BaseGrid());

	if (!list)
	{
		throw std::runtime_error("Input grid type is not point_list");
	}

	const auto stations = list->Stations();

	for (const auto& station : stations)<commit_msg>Use param.name isntead of id when fetching previ data from database<commit_after>/**
 * @file radon.cpp
 *
 */

#include "radon.h"
#include "logger.h"
#include "plugin_factory.h"
#include "point_list.h"
#include "util.h"
#include <sstream>
#include <thread>

using namespace std;
using namespace himan::plugin;

const int MAX_WORKERS = 32;
static once_flag oflag;
static map<string, string> tableNameCache;
static mutex tableNameMutex;

void radon::Init()
{
	if (!itsInit)
	{
		string radonHost = "vorlon";

		try
		{
			radonHost = util::GetEnv("RADON_HOSTNAME");
		}
		catch (...)
		{
		}

		string radonName = "radon";

		try
		{
			radonName = util::GetEnv("RADON_DATABASENAME");
		}
		catch (...)
		{
		}

		try
		{
			call_once(oflag, [&]() {
				NFmiRadonDBPool::Instance()->Username("wetodb");
				NFmiRadonDBPool::Instance()->Password(util::GetEnv("RADON_WETODB_PASSWORD"));
				NFmiRadonDBPool::Instance()->Database(radonName);
				NFmiRadonDBPool::Instance()->Hostname(radonHost);

				if (NFmiRadonDBPool::Instance()->MaxWorkers() < MAX_WORKERS)
				{
					NFmiRadonDBPool::Instance()->MaxWorkers(MAX_WORKERS);
				}
				itsLogger.Info("Connected to radon (db=" + radonName + ", host=" + radonHost + ")");
			});

			itsRadonDB = std::unique_ptr<NFmiRadonDB>(NFmiRadonDBPool::Instance()->GetConnection());
		}
		catch (int e)
		{
			itsLogger.Fatal("Failed to get connection");
			himan::Abort();
		}

		itsInit = true;
	}
}

radon::radon() : itsInit(false), itsRadonDB()
{
	itsLogger = logger("radon");
}
void radon::PoolMaxWorkers(int maxWorkers)
{
	NFmiRadonDBPool::Instance()->MaxWorkers(maxWorkers);
}
vector<std::string> radon::CSV(search_options& options)
{
	Init();

	vector<string> csv;

	if (options.prod.Class() != kPreviClass)
	{
		itsLogger.Error("Grid producer does not have csv based data");
		return csv;
	}

	stringstream query;

	const auto analtime = options.time.OriginDateTime().String();
	const auto key = to_string(options.prod.Id()) + "_" + analtime;
	string tableName;

	const auto mapValue = tableNameCache.find(key);

	if (mapValue == tableNameCache.end())
	{
		query << "SELECT table_name FROM as_previ WHERE producer_id = " << options.prod.Id()
		      << " AND (min_analysis_time, max_analysis_time) OVERLAPS ('" << analtime << "', '" << analtime << "')";

		itsRadonDB->Query(query.str());

		const auto row = itsRadonDB->FetchRow();

		if (row.empty())
		{
			itsLogger.Error("No tables found from as_previ for producer " + options.prod.Name());
			return csv;
		}

		tableName = row[0];

		lock_guard<mutex> lock(tableNameMutex);
		tableNameCache[key] = tableName;
	}
	else
	{
		tableName = (*mapValue).second;
	}

	string levelValue2 = "-1";

	if (!IsKHPMissingValue(options.level.Value2()))
	{
		levelValue2 = boost::lexical_cast<string>(options.level.Value2());
	}

	const string period = util::MakeSQLInterval(options.time);

	query.str("");

	query << "SELECT "
	      << "t.station_id,"
	      << "s.name AS station_name,"
	      << "st_x(s.position) AS longitude,"
	      << "st_y(s.position) AS latitude,"
	      << "t.value "
	      << "FROM " << tableName << " t, station s, param p "
	      << "WHERE "
	      << "t.station_id = s.id "
	      << "AND t.analysis_time = '" << analtime << "' "
	      << "AND t.param_id = p.id "
	      << "AND p.name = '" << options.param.Name() << "' "
	      << "AND t.level_id = " << options.level.Type() << " "
	      << "AND t.level_value = " << options.level.Value() << " "
	      << "AND (t.level_value2 = " << options.level.Value2() << " OR t.level_value2 = -1) "
	      << "AND t.forecast_period = '" << period << "' "
	      << "AND t.forecast_type_id = " << options.ftype.Type() << " "
	      << "AND t.forecast_type_value = " << options.ftype.Value() << " "
	      << "AND t.station_id IN (";

	const point_list* list = dynamic_cast<const point_list*>(options.configuration->BaseGrid());

	if (!list)
	{
		throw std::runtime_error("Input grid type is not point_list");
	}

	const auto stations = list->Stations();

	for (const auto& station : stations)
{'fraction_non_alphanumeric': 0.17624281788658505, 'fraction_numerical': 0.0029977516862353237, 'mean_word_length': 3.6742556917688267, 'pattern_counts': {'":': 0, '<': 197, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '495739', 'n_tokens_mistral': 3116, 'n_tokens_neox': 2845, 'n_words': 530}