mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 13:40:05 +00:00
Add GetCounties to county database
- Also remove mutex, as the database is only modified on initialization
This commit is contained in:
parent
7cf2121b8e
commit
bcc7391a19
3 changed files with 80 additions and 16 deletions
|
|
@ -1,7 +1,6 @@
|
||||||
#include <scwx/qt/config/county_database.hpp>
|
#include <scwx/qt/config/county_database.hpp>
|
||||||
#include <scwx/util/logger.hpp>
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
||||||
#include <shared_mutex>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <boost/uuid/uuid.hpp>
|
#include <boost/uuid/uuid.hpp>
|
||||||
|
|
@ -25,9 +24,12 @@ static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||||
|
|
||||||
static const std::string countyDatabaseFilename_ = ":/res/db/counties.db";
|
static const std::string countyDatabaseFilename_ = ":/res/db/counties.db";
|
||||||
|
|
||||||
|
typedef std::unordered_map<std::string, std::string> CountyMap;
|
||||||
|
typedef std::unordered_map<std::string, CountyMap> StateMap;
|
||||||
|
typedef std::unordered_map<char, StateMap> FormatMap;
|
||||||
|
|
||||||
static bool initialized_ {false};
|
static bool initialized_ {false};
|
||||||
static std::unordered_map<std::string, std::string> countyMap_;
|
static FormatMap countyDatabase_;
|
||||||
static std::shared_mutex countyMutex_;
|
|
||||||
static std::unordered_map<std::string, std::string> stateMap_;
|
static std::unordered_map<std::string, std::string> stateMap_;
|
||||||
|
|
||||||
void Initialize()
|
void Initialize()
|
||||||
|
|
@ -88,8 +90,8 @@ void Initialize()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Database is open, acquire lock
|
// Ensure counties exists
|
||||||
std::unique_lock lock(countyMutex_);
|
countyDatabase_.emplace('C', StateMap {});
|
||||||
|
|
||||||
// Query database for counties
|
// Query database for counties
|
||||||
rc = sqlite3_exec(
|
rc = sqlite3_exec(
|
||||||
|
|
@ -102,17 +104,26 @@ void Initialize()
|
||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
if (columns == 2)
|
if (columns == 2 && std::strlen(columnText[0]) == 6)
|
||||||
{
|
{
|
||||||
countyMap_.emplace(columnText[0], columnText[1]);
|
std::string fipsId = columnText[0];
|
||||||
|
std::string state = fipsId.substr(0, 2);
|
||||||
|
char type = fipsId.at(2);
|
||||||
|
|
||||||
|
countyDatabase_[type][state].emplace(fipsId, columnText[1]);
|
||||||
}
|
}
|
||||||
else
|
else if (columns != 2)
|
||||||
{
|
{
|
||||||
logger_->error(
|
logger_->error(
|
||||||
"County database format error, invalid number of columns: {}",
|
"County database format error, invalid number of columns: {}",
|
||||||
columns);
|
columns);
|
||||||
status = -1;
|
status = -1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger_->error("Invalid FIPS ID: {}", columnText[0]);
|
||||||
|
status = -1;
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
},
|
},
|
||||||
|
|
@ -157,9 +168,6 @@ void Initialize()
|
||||||
sqlite3_free(errorMessage);
|
sqlite3_free(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finished populating county map, release lock
|
|
||||||
lock.unlock();
|
|
||||||
|
|
||||||
// Close database
|
// Close database
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
|
|
||||||
|
|
@ -176,17 +184,47 @@ void Initialize()
|
||||||
|
|
||||||
std::string GetCountyName(const std::string& id)
|
std::string GetCountyName(const std::string& id)
|
||||||
{
|
{
|
||||||
std::shared_lock lock(countyMutex_);
|
if (id.length() > 3)
|
||||||
|
|
||||||
auto it = countyMap_.find(id);
|
|
||||||
if (it != countyMap_.cend())
|
|
||||||
{
|
{
|
||||||
return it->second;
|
// SSFNNN
|
||||||
|
char format = id.at(2);
|
||||||
|
std::string state = id.substr(0, 2);
|
||||||
|
|
||||||
|
auto stateIt = countyDatabase_.find(format);
|
||||||
|
if (stateIt != countyDatabase_.cend())
|
||||||
|
{
|
||||||
|
StateMap& states = stateIt->second;
|
||||||
|
auto countyIt = states.find(state);
|
||||||
|
if (countyIt != states.cend())
|
||||||
|
{
|
||||||
|
CountyMap& counties = countyIt->second;
|
||||||
|
auto it = counties.find(id);
|
||||||
|
if (it != counties.cend())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::string>
|
||||||
|
GetCounties(const std::string& state)
|
||||||
|
{
|
||||||
|
std::unordered_map<std::string, std::string> counties {};
|
||||||
|
|
||||||
|
StateMap& states = countyDatabase_.at('C');
|
||||||
|
auto it = states.find(state);
|
||||||
|
if (it != states.cend())
|
||||||
|
{
|
||||||
|
counties = it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return counties;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace CountyDatabase
|
} // namespace CountyDatabase
|
||||||
} // namespace config
|
} // namespace config
|
||||||
} // namespace qt
|
} // namespace qt
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace scwx
|
namespace scwx
|
||||||
|
|
@ -15,6 +16,8 @@ namespace CountyDatabase
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
std::string GetCountyName(const std::string& id);
|
std::string GetCountyName(const std::string& id);
|
||||||
|
std::unordered_map<std::string, std::string>
|
||||||
|
GetCounties(const std::string& state);
|
||||||
|
|
||||||
} // namespace CountyDatabase
|
} // namespace CountyDatabase
|
||||||
} // namespace config
|
} // namespace config
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,12 @@ class CountyDatabaseTest :
|
||||||
virtual void SetUp() { scwx::qt::config::CountyDatabase::Initialize(); }
|
virtual void SetUp() { scwx::qt::config::CountyDatabase::Initialize(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CountyCountTest :
|
||||||
|
public testing::TestWithParam<std::pair<std::string, std::size_t>>
|
||||||
|
{
|
||||||
|
virtual void SetUp() { scwx::qt::config::CountyDatabase::Initialize(); }
|
||||||
|
};
|
||||||
|
|
||||||
TEST_P(CountyDatabaseTest, CountyName)
|
TEST_P(CountyDatabaseTest, CountyName)
|
||||||
{
|
{
|
||||||
auto& [id, name] = GetParam();
|
auto& [id, name] = GetParam();
|
||||||
|
|
@ -24,6 +30,15 @@ TEST_P(CountyDatabaseTest, CountyName)
|
||||||
EXPECT_EQ(actualName, name);
|
EXPECT_EQ(actualName, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(CountyCountTest, State)
|
||||||
|
{
|
||||||
|
auto& [state, size] = GetParam();
|
||||||
|
|
||||||
|
auto counties = CountyDatabase::GetCounties(state);
|
||||||
|
|
||||||
|
EXPECT_EQ(counties.size(), size);
|
||||||
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
CountyDatabase,
|
CountyDatabase,
|
||||||
CountyDatabaseTest,
|
CountyDatabaseTest,
|
||||||
|
|
@ -33,6 +48,14 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
std::make_pair("GMZ335", "Galveston Bay"),
|
std::make_pair("GMZ335", "Galveston Bay"),
|
||||||
std::make_pair("ANZ338", "New York Harbor")));
|
std::make_pair("ANZ338", "New York Harbor")));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(CountyDatabase,
|
||||||
|
CountyCountTest,
|
||||||
|
testing::Values(std::make_pair("AZ", 15),
|
||||||
|
std::make_pair("MO", 115),
|
||||||
|
std::make_pair("TX", 254),
|
||||||
|
std::make_pair("GM", 0),
|
||||||
|
std::make_pair("AN", 0)));
|
||||||
|
|
||||||
} // namespace config
|
} // namespace config
|
||||||
} // namespace qt
|
} // namespace qt
|
||||||
} // namespace scwx
|
} // namespace scwx
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue