11#include <QMutexLocker>
12#include <QTemporaryDir>
13#include <qsqldatabase.h>
14#include "cachingdms.h"
15#include "catalogsdb.h"
19#include "final_action.h"
20#include "sqlstatements.cpp"
22using namespace CatalogsDB;
27int get_connection_index()
29 static int connection_index = 0;
30 return connection_index++;
37 query.setForwardOnly(forward_only);
38 if (!
query.prepare(statement))
40 throw DatabaseError(
"Can't prepare query!", DatabaseError::ErrorType::PREPARE,
50std::pair<bool, QString> migrate_db(
const int version,
QSqlDatabase &db,
53 if (prefix.size() > 0)
60 const auto success = add_ts.
exec(
QString(
"ALTER TABLE %1catalogs ADD COLUMN "
61 "timestamp DEFAULT NULL")
64 return {
false, add_ts.lastError().text() };
69 if (version < 3 && prefix ==
"")
72 const auto success = add_colors.
exec(SqlStatements::create_colors_table);
74 return {
false, add_colors.lastError().text() };
89 DatabaseError::ErrorType::OPEN, m_db.
lastError());
93 std::tie(m_db_version, m_htmesh_level, init) = get_db_meta();
95 if (!init && m_db_version > 0 && m_db_version < SqlStatements::current_db_version)
97 const auto &backup_path =
QString(
"%1.%2").
arg(m_db_file).
arg(
103 QString(
"Could not backup dso database before upgrading."),
104 DatabaseError::ErrorType::VERSION,
QSqlError{});
107 const auto &success = migrate_db(m_db_version, m_db);
110 m_db_version = SqlStatements::current_db_version;
112 version_query.
prepare(SqlStatements::update_version);
113 version_query.bindValue(
":version", m_db_version);
115 if (!version_query.exec())
118 DatabaseError::ErrorType::VERSION,
119 version_query.lastError());
124 QString(
"Wrong database version. Expected %1 and got %2 and "
125 "migration is not possible.")
126 .arg(SqlStatements::current_db_version)
128 DatabaseError::ErrorType::VERSION, success.second);
132 master_exists.
exec(SqlStatements::exists_master);
133 const bool master_does_exist = master_exists.next();
134 master_exists.finish();
136 if (init || !master_does_exist)
138 if (!initialize_db())
141 DatabaseError::ErrorType::INIT, m_db.
lastError());
148 SqlStatements::user_catalog_name,
true,
true, 1);
152 DatabaseError::ErrorType::CREATE_CATALOG, res.second);
159 DatabaseError::ErrorType::CREATE_CATALOG,
166 DatabaseError::ErrorType::CREATE_MASTER,
171 m_q_cat_by_id = make_query(m_db, SqlStatements::get_catalog_by_id,
true);
172 m_q_obj_by_trixel = make_query(m_db, SqlStatements::dso_by_trixel,
false);
173 m_q_obj_by_trixel_no_nulls = make_query(m_db, SqlStatements::dso_by_trixel_no_nulls,
false);
174 m_q_obj_by_trixel_null_mag = make_query(m_db, SqlStatements::dso_by_trixel_null_mag,
false);
175 m_q_obj_by_name = make_query(m_db, SqlStatements::dso_by_name,
true);
176 m_q_obj_by_name_exact = make_query(m_db, SqlStatements::dso_by_name_exact,
true);
177 m_q_obj_by_lim = make_query(m_db, SqlStatements::dso_by_lim,
true);
178 m_q_obj_by_maglim = make_query(m_db, SqlStatements::dso_by_maglim,
true);
179 m_q_obj_by_maglim_and_type =
180 make_query(m_db, SqlStatements::dso_by_maglim_and_type,
true);
181 m_q_obj_by_oid = make_query(m_db, SqlStatements::dso_by_oid,
true);
186bool DBManager::initialize_db()
188 if (m_db_version < 0 || m_htmesh_level < 1)
189 throw std::runtime_error(
"DBManager not initialized properly, m_db_vesion and "
190 "m_htmesh_level have to be set.");
192 if (!m_db.
exec(SqlStatements::create_meta_table).
isActive())
195 if (!m_db.
exec(SqlStatements::create_colors_table).
isActive())
199 meta_query.
prepare(SqlStatements::set_meta);
200 meta_query.bindValue(0, m_db_version);
201 meta_query.bindValue(1, m_htmesh_level);
202 meta_query.bindValue(2,
false);
204 if (!meta_query.exec())
207 return m_db.
exec(SqlStatements::create_catalog_list_table).
isActive();
210std::tuple<int, int, bool> DBManager::get_db_meta()
212 auto query = m_db.
exec(SqlStatements::get_meta);
215 return {
query.value(0).toInt(),
query.value(1).toInt(),
216 query.value(2).toBool() };
218 return { SqlStatements::current_db_version, SqlStatements::default_htmesh_level,
222std::vector<int> DBManager::get_catalog_ids(
bool include_disabled)
224 auto query = m_db.
exec(include_disabled ? SqlStatements::get_all_catalog_ids :
225 SqlStatements::get_catalog_ids);
227 std::vector<int> ids;
231 int id =
query.value(0).toInt();
240 const auto &ids = get_catalog_ids();
242 auto _ = gsl::finally([&]()
250 query.exec(
QString(
"DROP VIEW IF EXISTS ") + SqlStatements::all_catalog_view);
262 view += SqlStatements::all_catalog_view;
266 for (
auto *field : SqlStatements::catalog_collumns)
268 prefixed <<
QString(
"c.") + field;
271 QString prefixed_joined = prefixed.join(
",");
276 catalog_queries << SqlStatements::all_catalog_view_body(
277 prefixed_joined, SqlStatements::catalog_prefix,
id);
282 catalog_queries << SqlStatements::all_catalog_view_body(
283 prefixed_joined, SqlStatements::catalog_prefix, 0) +
287 view += catalog_queries.
join(
"\nUNION ALL\n");
288 result &= query.exec(view);
294 query.bindValue(
":id", cat.
id);
295 query.bindValue(
":name", cat.
name);
296 query.bindValue(
":mut", cat.
mut);
297 query.bindValue(
":enabled", cat.
enabled);
298 query.bindValue(
":precedence", cat.
precedence);
299 query.bindValue(
":author", cat.
author);
300 query.bindValue(
":source", cat.
source);
302 query.bindValue(
":version", cat.
version);
303 query.bindValue(
":color", cat.
color);
304 query.bindValue(
":license", cat.
license);
305 query.bindValue(
":maintainer", cat.
maintainer);
306 query.bindValue(
":timestamp", cat.
timestamp);
310 const int id,
const QString &name,
const bool mut,
const bool enabled,
311 const double precedence,
const QString &author,
const QString &source,
312 const QString &description,
const int version,
const QString &color,
315 return register_catalog({ id, name, precedence, author, source, description, mut,
316 enabled, version, color, license, maintainer, timestamp });
322 return {
false,
i18n(
"Catalog with that ID already exists.") };
326 if (!
query.exec(SqlStatements::create_catalog_table(cat.
id)))
328 return {
false,
query.lastError().text() };
331 query.prepare(SqlStatements::insert_catalog);
332 bind_catalog(query, cat);
334 return {
query.exec(),
query.lastError().text() };
339 auto _ = gsl::finally([&]()
346 if (!query.exec(SqlStatements::drop_master))
351 if (!query.exec(SqlStatements::create_master))
357 success &= query.exec(SqlStatements::create_master_trixel_index);
358 success &= query.exec(SqlStatements::create_master_mag_index);
359 success &= query.exec(SqlStatements::create_master_type_index);
360 success &= query.exec(SqlStatements::create_master_name_index);
366 return { query.value(
"id").toInt(),
367 query.value(
"name").toString(),
368 query.value(
"precedence").toDouble(),
369 query.value(
"author").toString(),
370 query.value(
"source").toString(),
371 query.value(
"description").toString(),
372 query.value(
"mut").toBool(),
373 query.value(
"enabled").toBool(),
374 query.value(
"version").toInt(),
375 query.value(
"color").toString(),
376 query.value(
"license").toString(),
377 query.value(
"maintainer").toString(),
378 query.value(
"timestamp").toDateTime() };
386 if (!m_q_cat_by_id.
exec())
387 return {
false, {} };
389 if (!m_q_cat_by_id.
next())
390 return {
false, {} };
392 Catalog cat{ read_catalog(m_q_cat_by_id) };
395 return {
true, cat };
402 auto end = gsl::finally([&]()
407 if (!m_q_cat_by_id.
exec())
410 return m_q_cat_by_id.
next();
429 const double ra =
query.value(2).toDouble();
430 const double dec =
query.value(3).toDouble();
431 const float mag =
query.isNull(4) ? NaN::f :
query.value(4).toFloat();
434 const QString catalog_identifier =
query.value(7).toString();
435 const float major =
query.value(8).toFloat();
436 const float minor =
query.value(9).toFloat();
437 const double position_angle =
query.value(10).toDouble();
438 const float flux =
query.value(11).toFloat();
439 const int catalog_id =
query.value(12).toInt();
442 mag,
name, long_name, catalog_identifier,
443 catalog_id, major, minor, position_angle,
447CatalogObjectVector DBManager::_get_objects_in_trixel_generic(
QSqlQuery &query,
const int trixel)
450 query.bindValue(0, trixel);
454 QString(
"The by-trixel query for objects in trixel=%1 failed.")
456 DatabaseError::ErrorType::UNKNOWN,
query.lastError());
458 CatalogObjectVector objects;
468 objects.reserve(count);
470 while (
query.previous())
472 objects.push_back(read_catalogobject(query));
481CatalogObjectList DBManager::fetch_objects(
QSqlQuery &query)
const
483 CatalogObjectList objects;
484 auto _ = gsl::finally([&]()
491 if (!
query.isActive())
494 objects.push_back(read_catalogobject(query));
500 const bool exactMatchOnly)
506 return CatalogObjectList();
509 m_q_obj_by_name_exact.
bindValue(
":name", name);
510 CatalogObjectList objs { fetch_objects(m_q_obj_by_name_exact) };
512 if ((limit == 1 && objs.size() > 0) || exactMatchOnly)
515 Q_ASSERT(objs.size() <= 1);
517 m_q_obj_by_name.
bindValue(
":name", name);
518 m_q_obj_by_name.
bindValue(
":limit",
int(limit - objs.size()));
520 CatalogObjectList moreObjects = fetch_objects(m_q_obj_by_name);
521 moreObjects.splice(moreObjects.begin(), objs);
527 const QString &name,
const int limit)
531 query.prepare(SqlStatements::dso_by_name_and_catalog(catalog_id));
532 query.bindValue(
":name", name);
533 query.bindValue(
":limit", limit);
534 query.bindValue(
":catalog", catalog_id);
536 return fetch_objects(query);
539std::pair<bool, CatalogObject> DBManager::read_first_object(
QSqlQuery &query)
const
541 if (!query.exec() || !query.first())
542 return {
false, {} };
544 return {
true, read_catalogobject(query) };
552 auto f = gsl::finally([&]()
557 return read_first_object(m_q_obj_by_oid);
561 const int catalog_id)
566 query.prepare(SqlStatements::dso_by_oid_and_catalog(catalog_id));
567 query.bindValue(0, oid);
569 return read_first_object(query);
575 m_q_obj_by_maglim.
bindValue(
":maglim", maglim);
576 m_q_obj_by_maglim.
bindValue(
":limit", limit);
578 return fetch_objects(m_q_obj_by_maglim);
586 return fetch_objects(m_q_obj_by_lim);
592 m_q_obj_by_maglim_and_type.
bindValue(
":type", type);
593 m_q_obj_by_maglim_and_type.
bindValue(
":limit", limit);
594 m_q_obj_by_maglim_and_type.
bindValue(
":maglim", maglim);
596 return fetch_objects(m_q_obj_by_maglim_and_type);
600 const int catalog_id,
float maglim,
605 query.prepare(SqlStatements::dso_in_catalog_by_maglim(catalog_id));
606 query.bindValue(
":type", type);
607 query.bindValue(
":limit", limit);
608 query.bindValue(
":maglim", maglim);
609 return fetch_objects(query);
616 return {
false,
i18n(
"Catalog could not be found.") };
618 const auto &cat = success.second;
623 query.prepare(SqlStatements::enable_disable_catalog);
624 query.bindValue(
":enabled", enabled);
625 query.bindValue(
":id",
id);
633 auto ids = get_catalog_ids(include_disabled);
634 std::vector<Catalog> catalogs;
635 catalogs.reserve(ids.size());
637 std::transform(ids.cbegin(), ids.cend(), std::back_inserter(catalogs),
640 const auto &found = get_catalog(id);
646 QString(
"Could not retrieve the catalog with id=%1").arg(id));
652inline void bind_catalogobject(
QSqlQuery &query,
const int catalog_id,
656 const float a,
const float b,
const double pa,
657 const float flux, Trixel trixel,
660 query.prepare(SqlStatements::insert_dso(catalog_id));
662 query.bindValue(
":hash", new_id);
663 query.bindValue(
":oid", new_id);
664 query.bindValue(
":type",
static_cast<int>(t));
665 query.bindValue(
":ra", r.
Degrees());
666 query.bindValue(
":dec", d.Degrees());
667 query.bindValue(
":magnitude", (m < 99 && !std::isnan(m)) ? m :
QVariant{});
668 query.bindValue(
":name", n);
669 query.bindValue(
":long_name", lname.
length() > 0 ? lname :
QVariant{});
670 query.bindValue(
":catalog_identifier",
671 catalog_identifier.
length() > 0 ? catalog_identifier :
QVariant{});
672 query.bindValue(
":major_axis", a > 0 ? a :
QVariant{});
674 query.bindValue(
":position_angle", pa > 0 ? pa :
QVariant{});
676 query.bindValue(
":trixel", trixel);
677 query.bindValue(
":catalog", catalog_id);
680inline void bind_catalogobject(
QSqlQuery &query,
const int catalog_id,
697std::pair<bool, QString>
701 const float a,
const float b,
const double pa,
const float flux)
706 return {
false,
i18n(
"Catalog with id=%1 not found.", catalog_id) };
708 if (!success.second.mut)
709 return {
false,
i18n(
"Catalog is immutable!") };
718 bind_catalogobject(query, catalog_id, t, r, d, n, m, lname, catalog_identifier, a, b,
719 pa, flux, trixel, new_id);
723 auto err = query.lastError().text();
724 if (err.startsWith(
"UNIQUE"))
725 err =
i18n(
"The object is already in the catalog!");
727 return {
false,
i18n(
"Could not insert object! %1", err) };
739 query.prepare(SqlStatements::remove_dso(catalog_id));
740 query.bindValue(
":oid",
id);
743 return {
false, query.lastError().text() };
753 return {
false,
i18n(
"Catalog could not be found.") };
755 QFile file{ file_path };
757 return {
false,
i18n(
"Output file is not writable.") };
763 if (!query.exec(
QString(
"ATTACH [%1] AS tmp").arg(file_path)))
765 i18n(
"Could not attach output file.<br>%1", query.lastError().text()) };
768 auto _ = gsl::finally([&]()
771 query.exec(
"DETACH tmp");
775 QString(
"CREATE TABLE tmp.cat AS SELECT * FROM cat_%1").arg(catalog_id)))
776 return {
false,
i18n(
"Could not copy catalog to output file.<br>%1")
777 .
arg(query.lastError().text()) };
779 if (!query.exec(SqlStatements::create_catalog_registry(
"tmp.catalogs")))
780 return {
false,
i18n(
"Could not create catalog registry in output file.<br>%1")
781 .
arg(query.lastError().text()) };
783 query.prepare(SqlStatements::insert_into_catalog_registry(
"tmp.catalogs"));
785 auto cat = found.second;
787 bind_catalog(query, cat);
792 i18n(
"Could not insert catalog into registry in output file.<br>%1")
793 .
arg(query.lastError().text()) };
796 if (!query.exec(
QString(
"PRAGMA tmp.user_version = %1").arg(m_db_version)))
798 return {
false,
i18n(
"Could not insert set exported database version.<br>%1")
799 .
arg(query.lastError().text()) };
802 if (!query.exec(
QString(
"PRAGMA tmp.application_id = %1").arg(application_id)))
805 i18n(
"Could not insert set exported database application id.<br>%1")
806 .
arg(query.lastError().text()) };
813 const bool overwrite)
816 const auto new_path = tmp.
filePath(
"cat.kscat");
819 QFile file{ new_path };
821 return {
false,
i18n(
"Catalog file is not readable.") };
826 if (!query.exec(
QString(
"ATTACH [%1] AS tmp").arg(new_path)))
830 i18n(
"Could not attach input file.<br>%1", query.lastError().text()) };
833 auto _ = gsl::finally([&]()
836 query.exec(
"DETACH tmp");
839 if (!query.exec(
"PRAGMA tmp.application_id") || !query.next() ||
840 query.value(0).toInt() != CatalogsDB::application_id)
841 return {
false,
i18n(
"Invalid catalog file.") };
843 if (!query.exec(
"PRAGMA tmp.user_version") || !query.next() ||
844 query.value(0).toInt() < m_db_version)
846 const auto &success = migrate_db(query.value(0).toInt(), m_db,
"tmp");
848 return {
false,
i18n(
"Could not migrate old catalog format.<br>%1",
852 if (!query.exec(
"SELECT id FROM tmp.catalogs LIMIT 1") || !query.next())
854 i18n(
"Could read the catalog id.<br>%1", query.lastError().text()) };
856 const auto id = query.value(0).toInt();
863 if (!overwrite && found.second.mut)
864 return {
false,
i18n(
"Catalog already exists in the database!") };
866 auto success = remove_catalog_force(
id);
875 "INSERT INTO catalogs (id, name, mut, enabled, precedence, author, source, "
876 "description, version, color, license, maintainer, timestamp) SELECT id, "
877 "name, mut, enabled, precedence, author, source, description, version, "
878 "color, license, maintainer, timestamp FROM tmp.catalogs LIMIT 1") ||
879 !query.exec(
QString(
"CREATE TABLE cat_%1 AS SELECT * FROM tmp.cat").arg(
id)))
881 i18n(
"Could not import the catalog.<br>%1", query.lastError().text()) };
886 return {
false,
i18n(
"Could not refresh the master catalog.<br>",
894 if (
id == SqlStatements::user_catalog_id)
895 return {
false,
i18n(
"Removing the user catalog is not allowed.") };
897 return remove_catalog_force(
id);
900std::pair<bool, QString> DBManager::remove_catalog_force(
const int id)
915 return {
false,
i18n(
"Could not remove the catalog from the registry.<br>%1")
929 return {
false,
i18n(
"Both catalogs have to exist!") };
932 return {
false,
i18n(
"Destination catalog has to be mutable!") };
936 if (!query.exec(SqlStatements::move_objects(id_1, id_2)))
937 return {
false, query.lastError().text() };
939 if (!query.exec(SqlStatements::set_catalog_all_objects(id_2)))
940 return {
false, query.lastError().text() };
948 return {
false,
i18n(
"Cannot update nonexisting catalog.") };
952 query.prepare(SqlStatements::update_catalog_meta);
953 query.bindValue(
":name", cat.
name);
954 query.bindValue(
":author", cat.
author);
955 query.bindValue(
":source", cat.
source);
957 query.bindValue(
":id", cat.
id);
958 query.bindValue(
":color", cat.
color);
959 query.bindValue(
":license", cat.
license);
960 query.bindValue(
":maintainer", cat.
maintainer);
961 query.bindValue(
":timestamp", cat.
timestamp);
963 return { query.exec(), query.lastError().text() };
971 const auto element = std::adjacent_find(
972 cats.cbegin(), cats.cend(), [](
const auto & c1,
const auto & c2)
974 return (c1.id >= CatalogsDB::custom_cat_min_id) &&
975 (c2.id >= CatalogsDB::custom_cat_min_id) && (c2.id - c1.id) > 1;
978 return std::max(CatalogsDB::custom_cat_min_id,
979 (element == cats.cend() ? cats.back().id : element->id) + 1);
982QString CatalogsDB::dso_db_path()
985 .
filePath(Options::dSOCatalogFilename());
988std::pair<bool, Catalog> CatalogsDB::read_catalog_meta_from_file(
const QString &path)
991 "QSQLITE",
QString(
"tmp_%1_%2").arg(path).arg(get_connection_index())) };
995 return {
false, {} };
999 if (!
query.exec(
"PRAGMA user_version") || !
query.next() ||
1000 query.value(0).toInt() < SqlStatements::current_db_version)
1003 const auto new_path = tmp.
filePath(
"cat.kscat");
1010 return {
false, {} };
1012 const auto &success = migrate_db(
query.value(0).toInt(), db);
1014 return {
false, {} };
1017 if (!
query.exec(SqlStatements::get_first_catalog) || !
query.first())
1018 return {
false, {} };
1021 return {
true, read_catalog(query) };
1027 while (
query.next())
1030 query.value(1).toInt();
1031 stats.total_count +=
query.value(1).toInt();
1039 if (!query.exec(SqlStatements::dso_count_by_type_master))
1040 return {
false, {} };
1042 return {
true, read_statistics(query) };
1045const std::pair<bool, CatalogStatistics>
1049 if (!query.exec(SqlStatements::dso_count_by_type(catalog_id)))
1050 return {
false, {} };
1052 return {
true, read_statistics(query) };
1055std::pair<bool, QString>
1057 const CatalogObjectVector &objects)
1060 const auto &success = get_catalog(catalog_id);
1062 return {
false,
i18n(
"Catalog with id=%1 not found.", catalog_id) };
1064 if (!success.second.mut)
1065 return {
false,
i18n(
"Catalog is immutable!") };
1070 for (
const auto &
object : objects)
1072 SkyPoint tmp{
object.ra(),
object.dec() };
1075 bind_catalogobject(query, catalog_id,
object, trixel);
1079 auto err = query.lastError().text();
1080 if (err.startsWith(
"UNIQUE"))
1081 err =
i18n(
"The object is already in the catalog!");
1083 return {
false,
i18n(
"Could not insert object! %1", err) };
1087 return { m_db.commit() &&update_catalog_views() &&compile_master_catalog(),
1088 m_db.lastError().text() };
1097 if (!query.prepare(SqlStatements::dso_by_wildcard()))
1101 query.bindValue(
":wildcard", wildcard);
1102 query.bindValue(
":limit", limit);
1104 return fetch_objects(query);
1107std::tuple<bool, const QString, CatalogObjectList>
1115 if (!query.prepare(SqlStatements::dso_general_query(where, order_by)))
1117 return {
false, query.lastError().text(), {} };
1120 query.bindValue(
":limit", limit);
1122 return {
false,
"", fetch_objects(query) };
1125CatalogsDB::CatalogColorMap CatalogsDB::parse_color_string(
const QString &str)
1127 CatalogsDB::CatalogColorMap colors{};
1131 const auto &parts = str.
split(
";");
1134 if (it->length() > 0)
1135 colors[
"default"] = *it;
1137 while (it != parts.constEnd())
1139 const auto &scheme = *(++it);
1140 if (it != parts.constEnd())
1142 const auto next = ++it;
1143 if (next == parts.constEnd())
1146 const auto &color = *next;
1147 colors[scheme] =
QColor(color);
1159QString CatalogsDB::to_color_string(CatalogColorMap colors)
1163 color_list << colors[
"default"].name();
1164 colors.
erase(
"default");
1166 for (
const auto &item : colors)
1168 if (item.second.isValid())
1170 color_list << item.
first << item.second.name();
1174 return color_list.
join(
";");
1184 if (!query.exec(SqlStatements::get_colors))
1189 colors[cat.
id] = parse_color_string(cat.
color);
1192 while (query.next())
1194 const auto &catalog = query.value(
"catalog").toInt();
1195 const auto &scheme = query.value(
"scheme").toString();
1196 const auto &color = query.value(
"color").toString();
1197 colors[catalog][scheme] =
QColor(color);
1205 return get_catalog_colors()[id];
1208std::pair<bool, QString>
1215 if (!query.prepare(SqlStatements::insert_color))
1217 return {
false, query.lastError().text() };
1220 query.bindValue(
":catalog",
id);
1221 for (
const auto &item : colors)
1223 query.bindValue(
":scheme", item.first);
1224 query.bindValue(
":color", item.second);
1227 return {
false, query.lastError().text() };
1230 return {
true,
"" };
a dms subclass that caches its sine and cosine values every time the angle is changed.
A simple container object to hold the minimum information for a Deep Sky Object to be drawn on the sk...
const oid getObjectId() const
const QString & catalogIdentifier() const
double pa() const override
Manages the catalog database and provides an interface to provide an interface to query and modify th...
CatalogObjectList get_objects_all()
Get all objects from the database.
std::pair< bool, QString > add_object(const int catalog_id, const SkyObject::TYPE t, const CachingDms &r, const CachingDms &d, const QString &n, const float m=NaN::f, const QString &lname=QString(), const QString &catalog_identifier=QString(), const float a=0.0, const float b=0.0, const double pa=0.0, const float flux=0)
Add a CatalogObject to a table with `catalog_id`.
int find_suitable_catalog_id()
Finds the smallest free id for a catalog.
bool compile_master_catalog()
Compiles the master catalog by merging the individual catalogs based on oid and precedence and create...
bool update_catalog_views()
Updates the all_catalog_view so that it includes all known catalogs.
CatalogObjectList find_objects_by_name(const QString &name, const int limit=-1, const bool exactMatchOnly=false)
Find an objects by name.
std::pair< bool, QString > set_catalog_enabled(const int id, const bool enabled)
Enable or disable a catalog.
ColorMap get_catalog_colors()
const std::pair< bool, CatalogStatistics > get_catalog_statistics(const int catalog_id)
CatalogObjectList find_objects_by_wildcard(const QString &wildcard, const int limit=-1)
Find an objects by searching the name four wildcard.
std::tuple< bool, const QString, CatalogObjectList > general_master_query(const QString &where, const QString &order_by="", const int limit=-1)
Find an objects by searching the master catlog with a query like SELECT ... FROM master WHERE \p wher...
std::pair< bool, QString > update_catalog_meta(const Catalog &cat)
Update the metatadata `catalog`.
std::pair< bool, QString > remove_catalog(const int id)
remove a catalog
const std::pair< bool, Catalog > get_catalog(const int id)
std::pair< bool, QString > remove_object(const int catalog_id, const CatalogObject::oid &id)
Remove the catalog object with the `oid` from the catalog with the `catalog_id`.
CatalogObjectList get_objects_in_catalog(SkyObject::TYPE type, const int catalog_id, float maglim=default_maglim, int limit=-1)
Get limit objects from the catalog with `catalog_id` of type with magnitude smaller than maglim (smal...
DBManager(const QString &filename)
Constructs a database manager from the filename which is resolved to a path in the kstars data direct...
std::pair< bool, QString > register_catalog(const int id, const QString &name, const bool mut, const bool enabled, const double precedence, const QString &author=cat_defaults.author, const QString &source=cat_defaults.source, const QString &description=cat_defaults.description, const int version=cat_defaults.version, const QString &color=cat_defaults.color, const QString &license=cat_defaults.license, const QString &maintainer=cat_defaults.maintainer, const QDateTime ×tamp=cat_defaults.timestamp)
Registers a new catalog in the database.
std::pair< bool, QString > import_catalog(const QString &file_path, const bool overwrite=false)
Loads a dumped catalog from path `file_path`.
std::pair< bool, QString > add_objects(const int catalog_id, const CatalogObjectVector &objects)
Add the `objects` to a table with `catalog_id`.
const std::vector< Catalog > get_catalogs(bool include_disabled=false)
CatalogObjectList get_objects(float maglim=default_maglim, int limit=-1)
Get limit objects with magnitude smaller than maglim (smaller = brighter) from the database.
bool catalog_exists(const int id)
std::pair< bool, QString > insert_catalog_colors(const int id, const CatalogColorMap &colors)
Saves the configures colors of the catalog with id id in colors into the database.
const std::pair< bool, CatalogStatistics > get_master_statistics()
std::pair< bool, QString > dump_catalog(int catalog_id, QString file_path)
Dumps the catalog with `id` into the file under the path file_path.
std::pair< bool, CatalogObject > get_object(const CatalogObject::oid &oid)
Get an object by `oid`.
std::pair< bool, QString > copy_objects(const int id_1, const int id_2)
Clone objects from the catalog with `id_1` to another with id_2.
Database related error, thrown when database access fails or an action does not succeed.
static SkyMesh * Create(int level)
creates the single instance of SkyMesh.
Trixel index(const SkyPoint *p)
returns the index of the trixel containing p.
virtual QString name(void) const
virtual QString longname(void) const
TYPE
The type classification of the SkyObject.
The sky coordinates of a point in the sky.
const CachingDms & ra0() const
const CachingDms & dec0() const
An angle, stored as degrees, but expressible in many ways.
const double & Degrees() const
QString i18n(const char *text, const TYPE &arg...)
Type type(const QSqlDatabase &db)
std::optional< QSqlQuery > query(const QString &queryStatement)
QString name(StandardAction id)
bool isValid() const const
QString name(NameFormat format) const const
QDateTime currentDateTime()
QString filePath(const QString &fileName) const const
bool copy(const QString &fileName, const QString &newName)
bool resize(const QString &fileName, qint64 sz)
virtual void close() override
const_iterator constBegin() const const
iterator erase(const_iterator begin, const_iterator end)
QSqlQuery exec(const QString &query) const const
QSqlDatabase addDatabase(QSqlDriver *driver, const QString &connectionName)
QSqlError lastError() const const
void setDatabaseName(const QString &name)
QString text() const const
void bindValue(const QString &placeholder, const QVariant &val, QSql::ParamType paramType)
bool isActive() const const
bool prepare(const QString &query)
QString arg(Args &&... args) const const
qsizetype length() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QString join(QChar separator) const const
QTextStream & dec(QTextStream &stream)
QString filePath(const QString &fileName) const const
Holds statistical information about the objects in a catalog.
A simple struct to hold information about catalogs.
QString color
The catalog color in the form [default color];[scheme file name];[color]....
QString maintainer
The catalog maintainer.
int version
The catalog version.
double precedence
The precedence level of a catalog.
QString name
The catalog mame.
bool enabled
Wether the catalog is enabled.
QString license
The catalog license.
QString description
A (short) description for the catalog.
QString author
The author of the catalog.
QString source
The catalog source.
bool mut
Wether the catalog is mutable.
QDateTime timestamp
Build time of the catalog.