12 #include <soci/soci.h> 13 #include <sqlite3/soci-sqlite3.h> 31 static constexpr std::string_view string_table =
"settings_string";
32 static constexpr std::string_view int_table =
"settings_int";
33 static constexpr std::string_view real_table =
"settings_real";
34 static constexpr std::string_view int_pair_table =
"settings_int_pair";
35 static constexpr std::string_view real_pair_table =
"settings_real_pair";
36 static constexpr std::string_view color_table =
"settings_color";
42 void transmitDataUpdate(
const std::string& dataName);
56 void initializeDatabase();
70 template<
typename T,
typename S>
73 if constexpr (is_integral_v<T>) {
75 sql <<
"SELECT value FROM " << int_table <<
" WHERE name = \"" << name <<
'"', soci::into(value, ind);
76 if (sql.got_data() && ind == soci::i_ok) {
80 }
else if constexpr (is_floating_point_v<T>) {
82 sql <<
"SELECT value FROM " << real_table <<
" WHERE name = \"" << name <<
'"', soci::into(value, ind);
83 if (sql.got_data() && ind == soci::i_ok) {
87 }
else if constexpr (is_base_of_v<std::array<int,2>, T>) {
89 sql <<
"SELECT a,b FROM " << int_pair_table <<
" WHERE name = \"" << name <<
'"', soci::into(r);
90 if (sql.got_data() && r.get_indicator(0) == soci::i_ok && r.get_indicator(1) == soci::i_ok) {
91 return T{r.get<
int>(0), r.get<
int>(1)};
94 }
else if constexpr (is_base_of_v<Size, T>) {
96 sql <<
"SELECT a,b FROM " << int_pair_table <<
" WHERE name = \"" << name <<
'"', soci::into(r);
97 if (sql.got_data() && r.get_indicator(0) == soci::i_ok && r.get_indicator(1) == soci::i_ok) {
98 return T{r.get<
int>(0), r.get<
int>(1)};
103 sql <<
"SELECT a,b FROM " << int_pair_table <<
" WHERE name = \"" << name <<
'"', soci::into(r);
104 if (sql.got_data() && r.get_indicator(0) == soci::i_ok && r.get_indicator(1) == soci::i_ok) {
105 return T{r.get<
int>(0), r.get<
int>(1)};
108 }
else if constexpr (is_base_of_v<std::array<double,2>, T>) {
110 sql <<
"SELECT a,b FROM " << real_pair_table <<
" WHERE name = \"" << name <<
'"', soci::into(r);
111 if (sql.got_data() && r.get_indicator(0) == soci::i_ok && r.get_indicator(1) == soci::i_ok) {
112 return T{r.get<
double>(0), r.get<
double>(1)};
115 }
else if constexpr (is_same_v<T, string> || is_same_v<T, const string> ||
116 is_same_v<T, string_view> || is_same_v<T, const string_view> ||
117 is_same_v<T, char *> || is_same_v<T, const char *>) {
119 sql <<
"SELECT value FROM " << string_table <<
" WHERE name = \"" << name <<
'"', soci::into(value, ind);
120 if (sql.got_data() && ind == soci::i_ok) {
124 }
else if constexpr (is_same_v<T, color::RGBA>) {
126 sql <<
"SELECT r,g,b,a FROM " << color_table <<
" WHERE name = \"" << name <<
'"', soci::into(r);
127 if (sql.got_data() && r.get_indicator(0) == soci::i_ok && r.get_indicator(1) == soci::i_ok
128 && r.get_indicator(2) == soci::i_ok && r.get_indicator(3) == soci::i_ok) {
130 value.
r() = r.get<
double>(0);
131 value.g() = r.get<
double>(1);
132 value.b() = r.get<
double>(2);
133 value.a() = r.get<
double>(3);
137 }
else if constexpr (is_same_v<T, color::HSVA>) {
139 sql <<
"SELECT r,g,b,a FROM " << color_table <<
" WHERE name = \"" << name <<
'"', soci::into(r);
140 if (sql.got_data() && r.get_indicator(0) == soci::i_ok && r.get_indicator(1) == soci::i_ok
141 && r.get_indicator(2) == soci::i_ok && r.get_indicator(3) == soci::i_ok) {
143 value.hue() = r.get<
double>(0);
144 value.saturation() = r.get<
double>(1);
145 value.value() = r.get<
double>(2);
146 value.alpha() = r.get<
double>(3);
151 static_assert(is_integral_v<T>,
"Value type not supported by Settings implementation." );
164 template<
typename T,
typename S>
166 if constexpr (is_integral_v<T>) {
167 sql <<
"INSERT OR REPLACE INTO " << int_table <<
" (name,value) VALUES (\"" << name <<
"\"," << value <<
')';
168 }
else if constexpr (is_floating_point_v<T>) {
169 sql <<
"INSERT OR REPLACE INTO " << real_table <<
" (name,value) VALUES (\"" << name <<
"\"," << value <<
')';
170 }
else if constexpr (is_base_of_v<std::array<int,2>,T>) {
171 sql <<
"INSERT OR REPLACE INTO " << int_pair_table <<
" (name,a,b) VALUES (\"" << name <<
"\"," 172 << value.at(0) <<
',' << value.at(1) <<
')';
173 }
else if constexpr (is_base_of_v<Size,T>) {
174 sql <<
"INSERT OR REPLACE INTO " << int_pair_table <<
" (name,a,b) VALUES (\"" << name <<
"\"," 175 << value.w <<
',' << value.h <<
')';
177 sql <<
"INSERT OR REPLACE INTO " << int_pair_table <<
" (name,a,b) VALUES (\"" << name <<
"\"," 178 << value.x <<
',' << value.y <<
')';
179 }
else if constexpr (is_base_of_v<std::array<double,2>,T>) {
180 sql <<
"INSERT OR REPLACE INTO " << real_pair_table <<
" (name,a,b) VALUES (\"" << name <<
"\"," << value.at(0) <<
',' << value.at(1) <<
')';
181 }
else if constexpr (is_same_v<T,string> || is_same_v<T,const string> ||
182 is_same_v<T,string_view> || is_same_v<T,const string_view> ||
183 is_same_v<T,char*> || is_same_v<T,const char *>) {
184 sql <<
"INSERT OR REPLACE INTO " << string_table <<
" (name,value) VALUES (\"" << name <<
"\",\"" << value <<
"\")";
185 }
else if constexpr (is_same_v<T, color::RGBA>) {
186 sql <<
"INSERT OR REPLACE INTO " << color_table <<
" (name,r,g,b,a) VALUES (\"" << name <<
"\"," 187 << value.r() <<
',' << value.g() <<
',' << value.lastPos() <<
',' << value.firstPos() <<
");";
188 }
else if constexpr (is_same_v<T, color::HSVA>) {
189 sql <<
"INSERT OR REPLACE INTO " << color_table <<
" (name,r,g,b,a) VALUES (\"" << name <<
"\"," 190 << (float)value.mHue <<
',' << value.mSaturation <<
',' << value.mLightness <<
',' << value.mAlpha <<
");";
192 static_assert(is_integral_v<T>,
"Value type not supported by Settings implementation." );
195 transmitDataUpdate(std::string{name});
205 template<
typename T,
typename S>
208 soci::session sql(soci::sqlite3, mDbPath.string());
209 setDatabaseValue<T>(sql, name, value);
210 }
catch (std::exception
const &e) {
211 std::cerr << e.what() <<
'\n';
222 template<
typename T,
typename S>
225 soci::session sql(soci::sqlite3, mDbPath.string());
226 return getDatabaseValue<T,S>(sql, name);
227 }
catch (std::exception
const &e) {
228 std::cerr << e.what() <<
'\n';
241 template<
typename T,
typename S>
243 auto value = getValue<T,S>(name);
245 return value.value();
void setDatabaseValue(soci::session &sql, S name, T value)
Set a value in the settings database.
Definition: Settings.h:165
A convenience structure that composes Signal and Slot types from a protocol signature, and provides a Slot factory.
Definition: Signals.h:122
std::filesystem::path mDbPath
The file path to the settings database.
Definition: Settings.h:29
Red Green Blue Alpha representation of a color.
Definition: Color.h:64
std::optional< T > getValue(S name)
Get a value in the settings database.
Definition: Settings.h:223
Hue Saturation Value (or Brightness) representation of a color.
Definition: Color.h:184
Definition: Settings.h:21
T getValue(S name, T defaultValue)
Get a value in the settings database, returning the default value if not found.
Definition: Settings.h:242
A settings database.
Definition: Settings.h:27
constexpr float & r() noexcept
Reference access to the Red value.
Definition: Color.h:107
ToDo: There is an issue that the initial scroll interaction is lost if the click/press lands on a Wid...
Definition: CelestialOverlay.cpp:13
The transmitter portion of a Signal-Slot transmitter receiver pair.
Definition: Signals.h:40
std::optional< T > getDatabaseValue(soci::session &sql, S name)
Get a value from settings the database.
Definition: Settings.h:71
Establish an intra-application signaling protocol.
void setValue(S name, T value)
Set a value in the settings database.
Definition: Settings.h:206