1 /*
2 SPDX-FileCopyrightText: 2012 Rishab Arora <ra.rishab@gmail.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "ksuserdb.h"
8
9 #include "artificialhorizoncomponent.h"
10 #include "kspaths.h"
11 #include "kstarsdata.h"
12 #include "linelist.h"
13 #include "version.h"
14
15 #include <QSqlQuery>
16 #include <QSqlRecord>
17 #include <QSqlTableModel>
18
19 #include <kstars_debug.h>
20
21 /*
22 * TODO (spacetime):
23 * The database supports storing logs. But it needs to be implemented.
24 *
25 * One of the unresolved problems was the creation of a unique identifier
26 * for each object (DSO,planet,star etc) for use in the database.
27 */
28
~KSUserDB()29 KSUserDB::~KSUserDB()
30 {
31 m_UserDB.close();
32
33 // Backup
34 QString current_dbfile = QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("userdb.sqlite");
35 QString backup_dbfile = QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("userdb.sqlite.backup");
36 QFile::remove(backup_dbfile);
37 QFile::copy(current_dbfile, backup_dbfile);
38 }
39
Initialize()40 bool KSUserDB::Initialize()
41 {
42 // Every logged in user has their own db.
43 m_UserDB = QSqlDatabase::addDatabase("QSQLITE", "userdb");
44 if (!m_UserDB.isValid())
45 {
46 qCCritical(KSTARS) << "Unable to prepare database of type sqlite!";
47 return false;
48 }
49
50 // If the database file does not exist, look for a backup
51 // If the database file exists and is empty, look for a backup
52 // If the database file exists and has data, use it.
53 // If the backup file does not exist, start fresh.
54 // If the backup file exists and has data, replace and use it.
55 // If the database file exists and has no data and the backup file exists, use it.
56 // If the database file exists and has no data and no backup file exists, start fresh.
57
58 QFileInfo dbfile(QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("userdb.sqlite"));
59 QFileInfo backup_file(QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("userdb.sqlite.backup"));
60
61 bool const first_run = !dbfile.exists() && !backup_file.exists();
62
63 m_UserDB.setDatabaseName(dbfile.filePath());
64
65 // If main fails to open and we have no backup, fail
66 if (!m_UserDB.open())
67 {
68 if (!backup_file.exists())
69 {
70 qCCritical(KSTARS) << QString("Failed opening user database '%1'.").arg(dbfile.filePath());
71 qCCritical(KSTARS) << LastError();
72 return false;
73 }
74 }
75
76 // If no main nor backup existed before opening, rebuild
77 if (m_UserDB.isOpen() && first_run)
78 {
79 qCInfo(KSTARS) << "User DB does not exist. New User DB will be created.";
80 FirstRun();
81 }
82
83 // If main appears empty/corrupted, restore if possible or rebuild
84 if (m_UserDB.tables().empty())
85 {
86 if (backup_file.exists())
87 {
88 m_UserDB.close();
89 qCWarning(KSTARS) << "Detected corrupted database. Attempting to recover from backup...";
90 QFile::remove(dbfile.filePath());
91 QFile::copy(backup_file.filePath(), dbfile.filePath());
92 QFile::remove(backup_file.filePath());
93 return Initialize();
94 }
95 else if (!FirstRun())
96 {
97 qCCritical(KSTARS) << QString("Failed initializing user database '%1.").arg(dbfile.filePath());
98 return false;
99 }
100 }
101
102 qCDebug(KSTARS) << "Opened the User DB. Ready.";
103
104 // Update table if previous version exists
105 QSqlTableModel version(nullptr, m_UserDB);
106 version.setTable("Version");
107 version.select();
108 QSqlRecord record = version.record(0);
109 version.clear();
110
111 // Old version had 2.9.5 ..etc, so we remove them
112 // Starting with 2.9.7, we are using SCHEMA_VERSION which now decoupled from KStars Version and starts at 300
113 int currentDBVersion = record.value("Version").toString().remove(".").toInt();
114
115 // Update database version to current KStars version
116 if (currentDBVersion != SCHEMA_VERSION)
117 {
118 QSqlQuery query(m_UserDB);
119 QString versionQuery = QString("UPDATE Version SET Version=%1").arg(SCHEMA_VERSION);
120 if (!query.exec(versionQuery))
121 qCWarning(KSTARS) << query.lastError();
122 }
123
124 // If prior to 2.9.4 extend filters table
125 if (currentDBVersion < 294)
126 {
127 QSqlQuery query(m_UserDB);
128
129 qCWarning(KSTARS) << "Detected old format filter table, re-creating...";
130 if (!query.exec("DROP table filter"))
131 qCWarning(KSTARS) << query.lastError();
132 if (!query.exec("CREATE TABLE filter ( "
133 "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
134 "Vendor TEXT DEFAULT NULL, "
135 "Model TEXT DEFAULT NULL, "
136 "Type TEXT DEFAULT NULL, "
137 "Color TEXT DEFAULT NULL,"
138 "Exposure REAL DEFAULT 1.0,"
139 "Offset INTEGER DEFAULT 0,"
140 "UseAutoFocus INTEGER DEFAULT 0,"
141 "LockedFilter TEXT DEFAULT '--',"
142 "AbsoluteFocusPosition INTEGER DEFAULT 0)"))
143 qCWarning(KSTARS) << query.lastError();
144 }
145
146 // If prior to 2.9.5 create fov table
147 if (currentDBVersion < 295)
148 {
149 QSqlQuery query(m_UserDB);
150
151 if (!query.exec("CREATE TABLE effectivefov ( "
152 "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
153 "Profile TEXT DEFAULT NULL, "
154 "Width INTEGER DEFAULT NULL, "
155 "Height INTEGER DEFAULT NULL, "
156 "PixelW REAL DEFAULT 5.0,"
157 "PixelH REAL DEFAULT 5.0,"
158 "FocalLength REAL DEFAULT 0.0,"
159 "FovW REAL DEFAULT 0.0,"
160 "FovH REAL DEFAULT 0.0)"))
161 qCWarning(KSTARS) << query.lastError();
162 }
163
164 if (currentDBVersion < 300)
165 {
166 QSqlQuery query(m_UserDB);
167 QString columnQuery = QString("ALTER TABLE profile ADD COLUMN remotedrivers TEXT DEFAULT NULL");
168 if (!query.exec(columnQuery))
169 qCWarning(KSTARS) << query.lastError();
170
171 if (m_UserDB.tables().contains("customdrivers") == false)
172 {
173 QSqlQuery query(m_UserDB);
174
175 if (!query.exec("CREATE TABLE customdrivers ( "
176 "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
177 "Name TEXT DEFAULT NULL, "
178 "Label TEXT DEFAULT NULL UNIQUE, "
179 "Manufacturer TEXT DEFAULT NULL, "
180 "Family TEXT DEFAULT NULL, "
181 "Exec TEXT DEFAULT NULL, "
182 "Version TEXT DEFAULT 1.0)"))
183 qCWarning(KSTARS) << query.lastError();
184 }
185 }
186
187 // Add manufacturer
188 if (currentDBVersion < 305)
189 {
190 QSqlQuery query(m_UserDB);
191 QString columnQuery = QString("ALTER TABLE customdrivers ADD COLUMN Manufacturer TEXT DEFAULT NULL");
192 if (!query.exec(columnQuery))
193 qCWarning(KSTARS) << query.lastError();
194 }
195
196 // Add indihub
197 if (currentDBVersion < 306)
198 {
199 QSqlQuery query(m_UserDB);
200 QString columnQuery = QString("ALTER TABLE profile ADD COLUMN indihub INTEGER DEFAULT 0");
201 if (!query.exec(columnQuery))
202 qCWarning(KSTARS) << query.lastError();
203 }
204
205 // Add Defect Map
206 if (currentDBVersion < 307)
207 {
208 QSqlQuery query(m_UserDB);
209 // If we are upgrading, remove all previous entries.
210 QString clearQuery = QString("DELETE FROM darkframe");
211 if (!query.exec(clearQuery))
212 qCWarning(KSTARS) << query.lastError();
213 QString columnQuery = QString("ALTER TABLE darkframe ADD COLUMN defectmap TEXT DEFAULT NULL");
214 if (!query.exec(columnQuery))
215 qCWarning(KSTARS) << query.lastError();
216 }
217
218 // Add port selector
219 if (currentDBVersion < 308)
220 {
221 QSqlQuery query(m_UserDB);
222 QString columnQuery = QString("ALTER TABLE profile ADD COLUMN portselector INTEGER DEFAULT 0");
223 if (!query.exec(columnQuery))
224 qCWarning(KSTARS) << query.lastError();
225 }
226
227 m_UserDB.close();
228 return true;
229 }
230
LastError()231 QSqlError KSUserDB::LastError()
232 {
233 // error description is in QSqlError::text()
234 return m_UserDB.lastError();
235 }
236
FirstRun()237 bool KSUserDB::FirstRun()
238 {
239 if (!RebuildDB())
240 return false;
241
242 /*ImportFlags();
243 ImportUsers();
244 ImportEquipment();*/
245
246 return true;
247 }
248
RebuildDB()249 bool KSUserDB::RebuildDB()
250 {
251 qCInfo(KSTARS) << "Rebuilding User Database";
252
253 QVector<QString> tables;
254 tables.append("CREATE TABLE Version ("
255 "Version CHAR DEFAULT NULL)");
256 tables.append("INSERT INTO Version VALUES (\"" KSTARS_VERSION "\")");
257 tables.append("CREATE TABLE user ( "
258 "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
259 "Name TEXT NOT NULL DEFAULT 'NULL', "
260 "Surname TEXT NOT NULL DEFAULT 'NULL', "
261 "Contact TEXT DEFAULT NULL)");
262
263 tables.append("CREATE TABLE telescope ( "
264 "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
265 "Vendor TEXT DEFAULT NULL, "
266 "Aperture REAL NOT NULL DEFAULT NULL, "
267 "Model TEXT DEFAULT NULL, "
268 "Driver TEXT DEFAULT NULL, "
269 "Type TEXT DEFAULT NULL, "
270 "FocalLength REAL DEFAULT NULL)");
271
272 tables.append("CREATE TABLE flags ( "
273 "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
274 "RA TEXT NOT NULL DEFAULT NULL, "
275 "Dec TEXT NOT NULL DEFAULT NULL, "
276 "Icon TEXT NOT NULL DEFAULT 'NULL', "
277 "Label TEXT NOT NULL DEFAULT 'NULL', "
278 "Color TEXT DEFAULT NULL, "
279 "Epoch TEXT DEFAULT NULL)");
280
281 tables.append("CREATE TABLE lens ( "
282 "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
283 "Vendor TEXT NOT NULL DEFAULT 'NULL', "
284 "Model TEXT DEFAULT NULL, "
285 "Factor REAL NOT NULL DEFAULT NULL)");
286
287 tables.append("CREATE TABLE eyepiece ( "
288 "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
289 "Vendor TEXT DEFAULT NULL, "
290 "Model TEXT DEFAULT NULL, "
291 "FocalLength REAL NOT NULL DEFAULT NULL, "
292 "ApparentFOV REAL NOT NULL DEFAULT NULL, "
293 "FOVUnit TEXT NOT NULL DEFAULT NULL)");
294
295 tables.append("CREATE TABLE filter ( "
296 "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
297 "Vendor TEXT DEFAULT NULL, "
298 "Model TEXT DEFAULT NULL, "
299 "Type TEXT DEFAULT NULL, "
300 "Color TEXT DEFAULT NULL,"
301 "Exposure REAL DEFAULT 1.0,"
302 "Offset INTEGER DEFAULT 0,"
303 "UseAutoFocus INTEGER DEFAULT 0,"
304 "LockedFilter TEXT DEFAULT '--',"
305 "AbsoluteFocusPosition INTEGER DEFAULT 0)");
306
307 tables.append("CREATE TABLE wishlist ( "
308 "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
309 "Date NUMERIC NOT NULL DEFAULT NULL, "
310 "Type TEXT DEFAULT NULL, "
311 "UIUD TEXT DEFAULT NULL)");
312
313 tables.append("CREATE TABLE fov ( "
314 "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
315 "name TEXT NOT NULL DEFAULT 'NULL', "
316 "color TEXT DEFAULT NULL, "
317 "sizeX NUMERIC DEFAULT NULL, "
318 "sizeY NUMERIC DEFAULT NULL, "
319 "shape TEXT DEFAULT NULL)");
320
321 tables.append("CREATE TABLE logentry ( "
322 "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
323 "content TEXT NOT NULL DEFAULT 'NULL', "
324 "UIUD TEXT DEFAULT NULL, "
325 "DateTime NUMERIC NOT NULL DEFAULT NULL, "
326 "User INTEGER DEFAULT NULL REFERENCES user (id), "
327 "Location TEXT DEFAULT NULL, "
328 "Telescope INTEGER DEFAULT NULL REFERENCES telescope (id),"
329 "Filter INTEGER DEFAULT NULL REFERENCES filter (id), "
330 "lens INTEGER DEFAULT NULL REFERENCES lens (id), "
331 "Eyepiece INTEGER DEFAULT NULL REFERENCES eyepiece (id), "
332 "FOV INTEGER DEFAULT NULL REFERENCES fov (id))");
333
334 // Note: enabled now encodes both a bool enabled value as well
335 // as another bool indicating if this is a horizon line or a ceiling line.
336 tables.append("CREATE TABLE horizons ( "
337 "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
338 "name TEXT NOT NULL,"
339 "label TEXT NOT NULL,"
340 "enabled INTEGER NOT NULL)");
341
342 tables.append("CREATE TABLE profile (id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, host "
343 "TEXT, port INTEGER, city TEXT, province TEXT, country TEXT, indiwebmanagerport INTEGER DEFAULT "
344 "NULL, autoconnect INTEGER DEFAULT 1, guidertype INTEGER DEFAULT 0, guiderhost TEXT, guiderport INTEGER,"
345 "primaryscope INTEGER DEFAULT 0, guidescope INTEGER DEFAULT 0, indihub INTEGER DEFAULT 0,"
346 "portselector INTEGER DEFAULT 1, remotedrivers TEXT DEFAULT NULL)");
347 tables.append("CREATE TABLE driver (id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, label TEXT NOT NULL, role "
348 "TEXT NOT NULL, profile INTEGER NOT NULL, FOREIGN KEY(profile) REFERENCES profile(id))");
349 //tables.append("CREATE TABLE custom_driver (id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, drivers TEXT NOT NULL, profile INTEGER NOT NULL, FOREIGN KEY(profile) REFERENCES profile(id))");
350
351 #ifdef Q_OS_WIN
352 tables.append("INSERT INTO profile (name, host, port) VALUES ('Simulators', 'localhost', 7624)");
353 #else
354 tables.append("INSERT INTO profile (name, portselector) VALUES ('Simulators', 0)");
355 #endif
356
357 tables.append("INSERT INTO driver (label, role, profile) VALUES ('Telescope Simulator', 'Mount', 1)");
358 tables.append("INSERT INTO driver (label, role, profile) VALUES ('CCD Simulator', 'CCD', 1)");
359 tables.append("INSERT INTO driver (label, role, profile) VALUES ('Focuser Simulator', 'Focuser', 1)");
360
361 tables.append("CREATE TABLE IF NOT EXISTS darkframe (id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, ccd TEXT "
362 "NOT NULL, chip INTEGER DEFAULT 0, binX INTEGER, binY INTEGER, temperature REAL, duration REAL, "
363 "filename TEXT NOT NULL, defectmap TEXT DEFAULT NULL, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP)");
364
365 tables.append("CREATE TABLE IF NOT EXISTS hips (ID TEXT NOT NULL UNIQUE,"
366 "obs_title TEXT NOT NULL, obs_description TEXT NOT NULL, hips_order TEXT NOT NULL,"
367 "hips_frame TEXT NOT NULL, hips_tile_width TEXT NOT NULL, hips_tile_format TEXT NOT NULL,"
368 "hips_service_url TEXT NOT NULL, moc_sky_fraction TEXT NOT NULL)");
369
370 tables.append("INSERT INTO hips (ID, obs_title, obs_description, hips_order, hips_frame, hips_tile_width, hips_tile_format, hips_service_url, moc_sky_fraction)"
371 "VALUES ('CDS/P/DSS2/color', 'DSS Colored', 'Color composition generated by CDS. This HiPS survey is based on 2 others HiPS surveys,"
372 " respectively DSS2-red and DSS2-blue HiPS, both of them directly generated from original scanned plates downloaded"
373 " from STScI site. The red component has been built from POSS-II F, AAO-SES,SR and SERC-ER plates. The blue component"
374 " has been build from POSS-II J and SERC-J,EJ. The green component is based on the mean of other components. Three"
375 " missing plates from red survey (253, 260, 359) has been replaced by pixels from the DSSColor STScI jpeg survey."
376 " The 11 missing blue plates (mainly in galactic plane) have not been replaced (only red component).',"
377 "'9', 'equatorial', '512', 'jpeg fits', 'http://alasky.u-strasbg.fr/DSS/DSSColor','1')");
378
379 tables.append("INSERT INTO hips (ID, obs_title, obs_description, hips_order, hips_frame, hips_tile_width, hips_tile_format, hips_service_url, moc_sky_fraction)"
380 "VALUES ('CDS/P/2MASS/color', '2MASS Color J (1.23 microns), H (1.66 microns), K (2.16 microns)',"
381 "'2MASS has uniformly scanned the entire sky in three near-infrared bands to detect and characterize point sources"
382 " brighter than about 1 mJy in each band, with signal-to-noise ratio (SNR) greater than 10, using a pixel size of"
383 " 2.0\". This has achieved an 80,000-fold improvement in sensitivity relative to earlier surveys. 2MASS used two"
384 " highly-automated 1.3-m telescopes, one at Mt. Hopkins, AZ, and one at CTIO, Chile. Each telescope was equipped with"
385 " a three-channel camera, each channel consisting of a 256x256 array of HgCdTe detectors, capable of observing the"
386 " sky simultaneously at J (1.25 microns), H (1.65 microns), and Ks (2.17 microns). The University of Massachusetts"
387 " (UMass) was responsible for the overall management of the project, and for developing the infrared cameras and"
388 " on-site computing systems at both facilities. The Infrared Processing and Analysis Center (IPAC) is responsible"
389 " for all data processing through the Production Pipeline, and construction and distribution of the data products."
390 " Funding is provided primarily by NASA and the NSF',"
391 "'9', 'equatorial', '512', 'jpeg fits', 'http://alaskybis.u-strasbg.fr/2MASS/Color', '1')");
392
393 tables.append("INSERT INTO hips (ID, obs_title, obs_description, hips_order, hips_frame, hips_tile_width, hips_tile_format, hips_service_url, moc_sky_fraction)"
394 "VALUES ('CDS/P/Fermi/color', 'Fermi Color HEALPix Survey', 'Launched on June 11, 2008, the Fermi Gamma-ray Space Telescope observes the cosmos using the"
395 " highest-energy form of light. This survey sums all data observed by the Fermi mission up to week 396. This version"
396 " of the Fermi survey are intensity maps where the summed counts maps are divided by the exposure for each pixel"
397 ". We anticipate using the HEASARC Hera capabilities to update this survey on a roughly quarterly basis. Data is"
398 " broken into 5 energy bands : 30-100 MeV Band 1, 100-300 MeV Band 2, 300-1000 MeV Band 3, 1-3 GeV Band 4 ,"
399 " 3-300 GeV Band 5. The SkyView data are based upon a Cartesian projection of the counts divided by the exposure maps."
400 " In the Cartesian projection pixels near the pole have a much smaller area than pixels on the equator, so these"
401 " pixels have smaller integrated flux. When creating large scale images in other projections users may wish to make"
402 " sure to compensate for this effect the flux conserving clip-resampling option.', '9', 'equatorial', '512', 'jpeg fits',"
403 "'http://alaskybis.u-strasbg.fr/Fermi/Color', '1')");
404
405
406 tables.append("CREATE TABLE dslr (id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
407 "Model TEXT DEFAULT NULL, "
408 "Width INTEGER DEFAULT NULL, "
409 "Height INTEGER DEFAULT NULL, "
410 "PixelW REAL DEFAULT 5.0,"
411 "PixelH REAL DEFAULT 5.0)");
412
413
414 tables.append("CREATE TABLE effectivefov ( "
415 "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
416 "Profile TEXT DEFAULT NULL, "
417 "Width INTEGER DEFAULT NULL, "
418 "Height INTEGER DEFAULT NULL, "
419 "PixelW REAL DEFAULT 5.0,"
420 "PixelH REAL DEFAULT 5.0,"
421 "FocalLength REAL DEFAULT 0.0,"
422 "FovW REAL DEFAULT 0.0,"
423 "FovH REAL DEFAULT 0.0)");
424
425 tables.append("CREATE TABLE customdrivers ( "
426 "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
427 "Name TEXT DEFAULT NULL, "
428 "Label TEXT DEFAULT NULL UNIQUE, "
429 "Manufacturer TEXT DEFAULT NULL, "
430 "Family TEXT DEFAULT NULL, "
431 "Exec TEXT DEFAULT NULL, "
432 "Version TEXT DEFAULT 1.0)");
433
434 for (int i = 0; i < tables.count(); ++i)
435 {
436 QSqlQuery query(m_UserDB);
437 if (!query.exec(tables[i]))
438 {
439 qCDebug(KSTARS) << query.lastError();
440 qCDebug(KSTARS) << query.executedQuery();
441 }
442 }
443
444 return true;
445 }
446
447 /*
448 * Observer Section
449 */
AddObserver(const QString & name,const QString & surname,const QString & contact)450 void KSUserDB::AddObserver(const QString &name, const QString &surname, const QString &contact)
451 {
452 m_UserDB.open();
453 QSqlTableModel users(nullptr, m_UserDB);
454 users.setTable("user");
455 users.setFilter("Name LIKE \'" + name + "\' AND Surname LIKE \'" + surname + "\'");
456 users.select();
457
458 if (users.rowCount() > 0)
459 {
460 QSqlRecord record = users.record(0);
461 record.setValue("Name", name);
462 record.setValue("Surname", surname);
463 record.setValue("Contact", contact);
464 users.setRecord(0, record);
465 users.submitAll();
466 }
467 else
468 {
469 int row = 0;
470 users.insertRows(row, 1);
471 users.setData(users.index(row, 1), name); // row0 is autoincerement ID
472 users.setData(users.index(row, 2), surname);
473 users.setData(users.index(row, 3), contact);
474 users.submitAll();
475 }
476
477 m_UserDB.close();
478 }
479
FindObserver(const QString & name,const QString & surname)480 bool KSUserDB::FindObserver(const QString &name, const QString &surname)
481 {
482 m_UserDB.open();
483 QSqlTableModel users(nullptr, m_UserDB);
484 users.setTable("user");
485 users.setFilter("Name LIKE \'" + name + "\' AND Surname LIKE \'" + surname + "\'");
486 users.select();
487
488 int observer_count = users.rowCount();
489
490 users.clear();
491 m_UserDB.close();
492 return (observer_count > 0);
493 }
494
495 // TODO(spacetime): This method is currently unused.
DeleteObserver(const QString & id)496 bool KSUserDB::DeleteObserver(const QString &id)
497 {
498 m_UserDB.open();
499 QSqlTableModel users(nullptr, m_UserDB);
500 users.setTable("user");
501 users.setFilter("id = \'" + id + "\'");
502 users.select();
503
504 users.removeRows(0, 1);
505 users.submitAll();
506
507 int observer_count = users.rowCount();
508
509 users.clear();
510 m_UserDB.close();
511 return (observer_count > 0);
512 }
GetDatabase()513 QSqlDatabase KSUserDB::GetDatabase()
514 {
515 m_UserDB.open();
516 return m_UserDB;
517 }
518 #ifndef KSTARS_LITE
GetAllObservers(QList<Observer * > & observer_list)519 void KSUserDB::GetAllObservers(QList<Observer *> &observer_list)
520 {
521 m_UserDB.open();
522 observer_list.clear();
523 QSqlTableModel users(nullptr, m_UserDB);
524 users.setTable("user");
525 users.select();
526
527 for (int i = 0; i < users.rowCount(); ++i)
528 {
529 QSqlRecord record = users.record(i);
530 QString id = record.value("id").toString();
531 QString name = record.value("Name").toString();
532 QString surname = record.value("Surname").toString();
533 QString contact = record.value("Contact").toString();
534 OAL::Observer *o = new OAL::Observer(id, name, surname, contact);
535 observer_list.append(o);
536 }
537
538 users.clear();
539 m_UserDB.close();
540 }
541 #endif
542
543 /* Dark Library Section */
544
545 /**
546 * @brief KSUserDB::AddDarkFrame Saves a new dark frame data to the database
547 * @param oneFrame Map that contains 1 to 1 correspondence with the database table, except for primary key and timestamp.
548 */
AddDarkFrame(const QVariantMap & oneFrame)549 void KSUserDB::AddDarkFrame(const QVariantMap &oneFrame)
550 {
551 m_UserDB.open();
552 QSqlTableModel darkframe(nullptr, m_UserDB);
553 darkframe.setTable("darkframe");
554 darkframe.select();
555
556 QSqlRecord record = darkframe.record();
557 // Remove PK so that it gets auto-incremented later
558 record.remove(0);
559 // Remove timestamp so that it gets auto-generated
560 record.remove(7);
561
562 for (QVariantMap::const_iterator iter = oneFrame.begin(); iter != oneFrame.end(); ++iter)
563 record.setValue(iter.key(), iter.value());
564
565 darkframe.insertRecord(-1, record);
566 darkframe.submitAll();
567
568 m_UserDB.close();
569 }
570
571 /**
572 * @brief KSUserDB::UpdateDarkFrame Updates an existing dark frame record in the data, replace all values matching the supplied ID
573 * @param oneFrame dark frame to update. The ID should already exist in the database.
574 */
UpdateDarkFrame(const QVariantMap & oneFrame)575 void KSUserDB::UpdateDarkFrame(const QVariantMap &oneFrame)
576 {
577 m_UserDB.open();
578 QSqlTableModel darkframe(nullptr, m_UserDB);
579 darkframe.setTable("darkframe");
580 darkframe.setFilter(QString("id=%1").arg(oneFrame["id"].toInt()));
581 darkframe.select();
582
583 QSqlRecord record = darkframe.record(0);
584 for (QVariantMap::const_iterator iter = oneFrame.begin(); iter != oneFrame.end(); ++iter)
585 record.setValue(iter.key(), iter.value());
586
587 darkframe.setRecord(0, record);
588 darkframe.submitAll();
589 m_UserDB.close();
590 }
591
592 /**
593 * @brief KSUserDB::DeleteDarkFrame Delete from database a dark frame record that matches the filename field.
594 * @param filename filename of dark frame to delete from database.
595 */
DeleteDarkFrame(const QString & filename)596 void KSUserDB::DeleteDarkFrame(const QString &filename)
597 {
598 m_UserDB.open();
599 QSqlTableModel darkframe(nullptr, m_UserDB);
600 darkframe.setTable("darkframe");
601 darkframe.setFilter("filename = \'" + filename + "\'");
602
603 darkframe.select();
604
605 darkframe.removeRows(0, 1);
606 darkframe.submitAll();
607
608 m_UserDB.close();
609 }
610
GetAllDarkFrames(QList<QVariantMap> & darkFrames)611 void KSUserDB::GetAllDarkFrames(QList<QVariantMap> &darkFrames)
612 {
613 darkFrames.clear();
614
615 m_UserDB.open();
616 QSqlTableModel darkframe(nullptr, m_UserDB);
617 darkframe.setTable("darkframe");
618 darkframe.select();
619
620 for (int i = 0; i < darkframe.rowCount(); ++i)
621 {
622 QVariantMap recordMap;
623 QSqlRecord record = darkframe.record(i);
624 for (int j = 0; j < record.count(); j++)
625 recordMap[record.fieldName(j)] = record.value(j);
626
627 darkFrames.append(recordMap);
628 }
629
630 m_UserDB.close();
631 }
632
633
634 /* Effective FOV Section */
635
AddEffectiveFOV(const QVariantMap & oneFOV)636 void KSUserDB::AddEffectiveFOV(const QVariantMap &oneFOV)
637 {
638 m_UserDB.open();
639 QSqlTableModel effectivefov(nullptr, m_UserDB);
640 effectivefov.setTable("effectivefov");
641 effectivefov.select();
642
643 QSqlRecord record = effectivefov.record();
644
645 // Remove PK so that it gets auto-incremented later
646 record.remove(0);
647
648 for (QVariantMap::const_iterator iter = oneFOV.begin(); iter != oneFOV.end(); ++iter)
649 record.setValue(iter.key(), iter.value());
650
651 effectivefov.insertRecord(-1, record);
652
653 effectivefov.submitAll();
654
655 m_UserDB.close();
656 }
657
DeleteEffectiveFOV(const QString & id)658 bool KSUserDB::DeleteEffectiveFOV(const QString &id)
659 {
660 m_UserDB.open();
661 QSqlTableModel effectivefov(nullptr, m_UserDB);
662 effectivefov.setTable("effectivefov");
663 effectivefov.setFilter("id = \'" + id + "\'");
664
665 effectivefov.select();
666
667 effectivefov.removeRows(0, 1);
668 effectivefov.submitAll();
669
670 m_UserDB.close();
671
672 return true;
673 }
674
GetAllEffectiveFOVs(QList<QVariantMap> & effectiveFOVs)675 void KSUserDB::GetAllEffectiveFOVs(QList<QVariantMap> &effectiveFOVs)
676 {
677 effectiveFOVs.clear();
678
679 m_UserDB.open();
680 QSqlTableModel effectivefov(nullptr, m_UserDB);
681 effectivefov.setTable("effectivefov");
682 effectivefov.select();
683
684 for (int i = 0; i < effectivefov.rowCount(); ++i)
685 {
686 QVariantMap recordMap;
687 QSqlRecord record = effectivefov.record(i);
688 for (int j = 0; j < record.count(); j++)
689 recordMap[record.fieldName(j)] = record.value(j);
690
691 effectiveFOVs.append(recordMap);
692 }
693
694 m_UserDB.close();
695 }
696
697 /* Driver Alias Section */
698
AddCustomDriver(const QVariantMap & oneDriver)699 bool KSUserDB::AddCustomDriver(const QVariantMap &oneDriver)
700 {
701 m_UserDB.open();
702 QSqlTableModel CustomDriver(nullptr, m_UserDB);
703 CustomDriver.setTable("customdrivers");
704 CustomDriver.select();
705
706 QSqlRecord record = CustomDriver.record();
707
708 // Remove PK so that it gets auto-incremented later
709 record.remove(0);
710
711 for (QVariantMap::const_iterator iter = oneDriver.begin(); iter != oneDriver.end(); ++iter)
712 record.setValue(iter.key(), iter.value());
713
714 bool rc = CustomDriver.insertRecord(-1, record);
715 if (rc == false)
716 return rc;
717
718 rc = CustomDriver.submitAll();
719
720 m_UserDB.close();
721
722 return rc;
723 }
724
DeleteCustomDriver(const QString & id)725 bool KSUserDB::DeleteCustomDriver(const QString &id)
726 {
727 m_UserDB.open();
728 QSqlTableModel CustomDriver(nullptr, m_UserDB);
729 CustomDriver.setTable("customdrivers");
730 CustomDriver.setFilter("id = \'" + id + "\'");
731
732 CustomDriver.select();
733
734 CustomDriver.removeRows(0, 1);
735 CustomDriver.submitAll();
736
737 m_UserDB.close();
738
739 return true;
740 }
741
GetAllCustomDrivers(QList<QVariantMap> & CustomDrivers)742 void KSUserDB::GetAllCustomDrivers(QList<QVariantMap> &CustomDrivers)
743 {
744 CustomDrivers.clear();
745
746 m_UserDB.open();
747 QSqlTableModel CustomDriver(nullptr, m_UserDB);
748 CustomDriver.setTable("customdrivers");
749 CustomDriver.select();
750
751 for (int i = 0; i < CustomDriver.rowCount(); ++i)
752 {
753 QVariantMap recordMap;
754 QSqlRecord record = CustomDriver.record(i);
755 for (int j = 0; j < record.count(); j++)
756 recordMap[record.fieldName(j)] = record.value(j);
757
758 CustomDrivers.append(recordMap);
759 }
760
761 m_UserDB.close();
762 }
763
764 /* HiPS Section */
765
AddHIPSSource(const QMap<QString,QString> & oneSource)766 void KSUserDB::AddHIPSSource(const QMap<QString, QString> &oneSource)
767 {
768 m_UserDB.open();
769 QSqlTableModel HIPSSource(nullptr, m_UserDB);
770 HIPSSource.setTable("hips");
771 HIPSSource.select();
772
773 QSqlRecord record = HIPSSource.record();
774
775 for (QMap<QString, QString>::const_iterator iter = oneSource.begin(); iter != oneSource.end(); ++iter)
776 record.setValue(iter.key(), iter.value());
777
778 HIPSSource.insertRecord(-1, record);
779
780 HIPSSource.submitAll();
781
782 m_UserDB.close();
783 }
784
DeleteHIPSSource(const QString & ID)785 bool KSUserDB::DeleteHIPSSource(const QString &ID)
786 {
787 m_UserDB.open();
788 QSqlTableModel HIPSSource(nullptr, m_UserDB);
789 HIPSSource.setTable("hips");
790 HIPSSource.setFilter("ID = \'" + ID + "\'");
791
792 HIPSSource.select();
793
794 HIPSSource.removeRows(0, 1);
795 HIPSSource.submitAll();
796
797 m_UserDB.close();
798
799 return true;
800 }
801
GetAllHIPSSources(QList<QMap<QString,QString>> & HIPSSources)802 void KSUserDB::GetAllHIPSSources(QList<QMap<QString, QString>> &HIPSSources)
803 {
804 HIPSSources.clear();
805
806 m_UserDB.open();
807 QSqlTableModel HIPSSource(nullptr, m_UserDB);
808 HIPSSource.setTable("hips");
809 HIPSSource.select();
810
811 for (int i = 0; i < HIPSSource.rowCount(); ++i)
812 {
813 QMap<QString, QString> recordMap;
814 QSqlRecord record = HIPSSource.record(i);
815 for (int j = 1; j < record.count(); j++)
816 recordMap[record.fieldName(j)] = record.value(j).toString();
817
818 HIPSSources.append(recordMap);
819 }
820
821 m_UserDB.close();
822 }
823
824
825 /* DSLR Section */
826
AddDSLRInfo(const QMap<QString,QVariant> & oneInfo)827 void KSUserDB::AddDSLRInfo(const QMap<QString, QVariant> &oneInfo)
828 {
829 m_UserDB.open();
830 QSqlTableModel DSLRInfo(nullptr, m_UserDB);
831 DSLRInfo.setTable("dslr");
832 DSLRInfo.select();
833
834 QSqlRecord record = DSLRInfo.record();
835
836 for (QMap<QString, QVariant>::const_iterator iter = oneInfo.begin(); iter != oneInfo.end(); ++iter)
837 record.setValue(iter.key(), iter.value());
838
839 DSLRInfo.insertRecord(-1, record);
840
841 DSLRInfo.submitAll();
842
843 m_UserDB.close();
844 }
845
DeleteAllDSLRInfo()846 bool KSUserDB::DeleteAllDSLRInfo()
847 {
848 m_UserDB.open();
849 QSqlTableModel DSLRInfo(nullptr, m_UserDB);
850 DSLRInfo.setTable("dslr");
851 DSLRInfo.select();
852
853 DSLRInfo.removeRows(0, DSLRInfo.rowCount());
854 DSLRInfo.submitAll();
855
856 m_UserDB.close();
857
858 return true;
859 }
860
DeleteDSLRInfo(const QString & model)861 bool KSUserDB::DeleteDSLRInfo(const QString &model)
862 {
863 m_UserDB.open();
864 QSqlTableModel DSLRInfo(nullptr, m_UserDB);
865 DSLRInfo.setTable("dslr");
866 DSLRInfo.setFilter("model = \'" + model + "\'");
867
868 DSLRInfo.select();
869
870 DSLRInfo.removeRows(0, 1);
871 DSLRInfo.submitAll();
872
873 m_UserDB.close();
874
875 return true;
876 }
877
GetAllDSLRInfos(QList<QMap<QString,QVariant>> & DSLRInfos)878 void KSUserDB::GetAllDSLRInfos(QList<QMap<QString, QVariant>> &DSLRInfos)
879 {
880 DSLRInfos.clear();
881
882 m_UserDB.open();
883 QSqlTableModel DSLRInfo(nullptr, m_UserDB);
884 DSLRInfo.setTable("dslr");
885 DSLRInfo.select();
886
887 for (int i = 0; i < DSLRInfo.rowCount(); ++i)
888 {
889 QMap<QString, QVariant> recordMap;
890 QSqlRecord record = DSLRInfo.record(i);
891 for (int j = 1; j < record.count(); j++)
892 recordMap[record.fieldName(j)] = record.value(j);
893
894 DSLRInfos.append(recordMap);
895 }
896
897 m_UserDB.close();
898 }
899
900 /*
901 * Flag Section
902 */
903
DeleteAllFlags()904 void KSUserDB::DeleteAllFlags()
905 {
906 m_UserDB.open();
907 QSqlTableModel flags(nullptr, m_UserDB);
908 flags.setEditStrategy(QSqlTableModel::OnManualSubmit);
909 flags.setTable("flags");
910 flags.select();
911
912 flags.removeRows(0, flags.rowCount());
913 flags.submitAll();
914
915 flags.clear();
916 m_UserDB.close();
917 }
918
AddFlag(const QString & ra,const QString & dec,const QString & epoch,const QString & image_name,const QString & label,const QString & labelColor)919 void KSUserDB::AddFlag(const QString &ra, const QString &dec, const QString &epoch, const QString &image_name,
920 const QString &label, const QString &labelColor)
921 {
922 m_UserDB.open();
923 QSqlTableModel flags(nullptr, m_UserDB);
924 flags.setTable("flags");
925
926 int row = 0;
927 flags.insertRows(row, 1);
928 flags.setData(flags.index(row, 1), ra); // row,0 is autoincerement ID
929 flags.setData(flags.index(row, 2), dec);
930 flags.setData(flags.index(row, 3), image_name);
931 flags.setData(flags.index(row, 4), label);
932 flags.setData(flags.index(row, 5), labelColor);
933 flags.setData(flags.index(row, 6), epoch);
934 flags.submitAll();
935
936 flags.clear();
937 m_UserDB.close();
938 }
939
GetAllFlags()940 QList<QStringList> KSUserDB::GetAllFlags()
941 {
942 QList<QStringList> flagList;
943
944 m_UserDB.open();
945 QSqlTableModel flags(nullptr, m_UserDB);
946 flags.setTable("flags");
947 flags.select();
948
949 for (int i = 0; i < flags.rowCount(); ++i)
950 {
951 QStringList flagEntry;
952 QSqlRecord record = flags.record(i);
953 /* flagEntry order description
954 * The variation in the order is due to variation
955 * in flag entry description order and flag database
956 * description order.
957 * flag (database): ra, dec, icon, label, color, epoch
958 * flag (object): ra, dec, epoch, icon, label, color
959 */
960 flagEntry.append(record.value(1).toString());
961 flagEntry.append(record.value(2).toString());
962 flagEntry.append(record.value(6).toString());
963 flagEntry.append(record.value(3).toString());
964 flagEntry.append(record.value(4).toString());
965 flagEntry.append(record.value(5).toString());
966 flagList.append(flagEntry);
967 }
968
969 flags.clear();
970 m_UserDB.close();
971 return flagList;
972 }
973
974 /*
975 * Generic Section
976 */
DeleteEquipment(const QString & type,const int & id)977 void KSUserDB::DeleteEquipment(const QString &type, const int &id)
978 {
979 m_UserDB.open();
980 QSqlTableModel equip(nullptr, m_UserDB);
981 equip.setTable(type);
982 equip.setFilter("id = " + QString::number(id));
983 equip.select();
984
985 equip.removeRows(0, equip.rowCount());
986 equip.submitAll();
987
988 equip.clear();
989 m_UserDB.close();
990 }
991
DeleteAllEquipment(const QString & type)992 void KSUserDB::DeleteAllEquipment(const QString &type)
993 {
994 m_UserDB.open();
995 QSqlTableModel equip(nullptr, m_UserDB);
996 equip.setEditStrategy(QSqlTableModel::OnManualSubmit);
997 equip.setTable(type);
998 equip.setFilter("id >= 1");
999 equip.select();
1000 equip.removeRows(0, equip.rowCount());
1001 equip.submitAll();
1002
1003 equip.clear();
1004 m_UserDB.close();
1005 }
1006
1007 /*
1008 * Telescope section
1009 */
AddScope(const QString & model,const QString & vendor,const QString & driver,const QString & type,const double & focalLength,const double & aperture)1010 void KSUserDB::AddScope(const QString &model, const QString &vendor, const QString &driver, const QString &type,
1011 const double &focalLength, const double &aperture)
1012 {
1013 m_UserDB.open();
1014 QSqlTableModel equip(nullptr, m_UserDB);
1015 equip.setTable("telescope");
1016
1017 int row = 0;
1018 equip.insertRows(row, 1);
1019 equip.setData(equip.index(row, 1), vendor); // row,0 is autoincerement ID
1020 equip.setData(equip.index(row, 2), aperture);
1021 equip.setData(equip.index(row, 3), model);
1022 equip.setData(equip.index(row, 4), driver);
1023 equip.setData(equip.index(row, 5), type);
1024 equip.setData(equip.index(row, 6), focalLength);
1025 equip.submitAll();
1026
1027 equip.clear(); //DB will not close if linked object not cleared
1028 m_UserDB.close();
1029 }
1030
AddScope(const QString & model,const QString & vendor,const QString & driver,const QString & type,const double & focalLength,const double & aperture,const QString & id)1031 void KSUserDB::AddScope(const QString &model, const QString &vendor, const QString &driver, const QString &type,
1032 const double &focalLength, const double &aperture, const QString &id)
1033 {
1034 m_UserDB.open();
1035 QSqlTableModel equip(nullptr, m_UserDB);
1036 equip.setTable("telescope");
1037 equip.setFilter("id = " + id);
1038 equip.select();
1039
1040 if (equip.rowCount() > 0)
1041 {
1042 QSqlRecord record = equip.record(0);
1043 record.setValue(1, vendor);
1044 record.setValue(2, aperture);
1045 record.setValue(3, model);
1046 record.setValue(4, driver);
1047 record.setValue(5, type);
1048 record.setValue(6, focalLength);
1049 equip.setRecord(0, record);
1050 equip.submitAll();
1051 }
1052
1053 m_UserDB.close();
1054 }
1055 #ifndef KSTARS_LITE
GetAllScopes(QList<Scope * > & scope_list)1056 void KSUserDB::GetAllScopes(QList<Scope *> &scope_list)
1057 {
1058 scope_list.clear();
1059
1060 m_UserDB.open();
1061 QSqlTableModel equip(nullptr, m_UserDB);
1062 equip.setTable("telescope");
1063 equip.select();
1064
1065 for (int i = 0; i < equip.rowCount(); ++i)
1066 {
1067 QSqlRecord record = equip.record(i);
1068 QString id = record.value("id").toString();
1069 QString vendor = record.value("Vendor").toString();
1070 double aperture = record.value("Aperture").toDouble();
1071 QString model = record.value("Model").toString();
1072 QString driver = record.value("Driver").toString();
1073 QString type = record.value("Type").toString();
1074 double focalLength = record.value("FocalLength").toDouble();
1075 OAL::Scope *o = new OAL::Scope(id, model, vendor, type, focalLength, aperture);
1076 o->setINDIDriver(driver);
1077 scope_list.append(o);
1078 }
1079
1080 equip.clear();
1081 m_UserDB.close();
1082 }
1083 #endif
1084 /*
1085 * Eyepiece section
1086 */
AddEyepiece(const QString & vendor,const QString & model,const double & focalLength,const double & fov,const QString & fovunit)1087 void KSUserDB::AddEyepiece(const QString &vendor, const QString &model, const double &focalLength, const double &fov,
1088 const QString &fovunit)
1089 {
1090 m_UserDB.open();
1091 QSqlTableModel equip(nullptr, m_UserDB);
1092 equip.setTable("eyepiece");
1093
1094 int row = 0;
1095 equip.insertRows(row, 1);
1096 equip.setData(equip.index(row, 1), vendor); // row,0 is autoincerement ID
1097 equip.setData(equip.index(row, 2), model);
1098 equip.setData(equip.index(row, 3), focalLength);
1099 equip.setData(equip.index(row, 4), fov);
1100 equip.setData(equip.index(row, 5), fovunit);
1101 equip.submitAll();
1102
1103 equip.clear();
1104 m_UserDB.close();
1105 }
1106
AddEyepiece(const QString & vendor,const QString & model,const double & focalLength,const double & fov,const QString & fovunit,const QString & id)1107 void KSUserDB::AddEyepiece(const QString &vendor, const QString &model, const double &focalLength, const double &fov,
1108 const QString &fovunit, const QString &id)
1109 {
1110 m_UserDB.open();
1111 QSqlTableModel equip(nullptr, m_UserDB);
1112 equip.setTable("eyepiece");
1113 equip.setFilter("id = " + id);
1114 equip.select();
1115
1116 if (equip.rowCount() > 0)
1117 {
1118 QSqlRecord record = equip.record(0);
1119 record.setValue(1, vendor);
1120 record.setValue(2, model);
1121 record.setValue(3, focalLength);
1122 record.setValue(4, fov);
1123 record.setValue(5, fovunit);
1124 equip.setRecord(0, record);
1125 equip.submitAll();
1126 }
1127
1128 m_UserDB.close();
1129 }
1130 #ifndef KSTARS_LITE
GetAllEyepieces(QList<OAL::Eyepiece * > & eyepiece_list)1131 void KSUserDB::GetAllEyepieces(QList<OAL::Eyepiece *> &eyepiece_list)
1132 {
1133 eyepiece_list.clear();
1134
1135 m_UserDB.open();
1136 QSqlTableModel equip(nullptr, m_UserDB);
1137 equip.setTable("eyepiece");
1138 equip.select();
1139
1140 for (int i = 0; i < equip.rowCount(); ++i)
1141 {
1142 QSqlRecord record = equip.record(i);
1143 QString id = record.value("id").toString();
1144 QString vendor = record.value("Vendor").toString();
1145 QString model = record.value("Model").toString();
1146 double focalLength = record.value("FocalLength").toDouble();
1147 double fov = record.value("ApparentFOV").toDouble();
1148 QString fovUnit = record.value("FOVUnit").toString();
1149
1150 OAL::Eyepiece *o = new OAL::Eyepiece(id, model, vendor, fov, fovUnit, focalLength);
1151 eyepiece_list.append(o);
1152 }
1153
1154 equip.clear();
1155 m_UserDB.close();
1156 }
1157 #endif
1158 /*
1159 * lens section
1160 */
AddLens(const QString & vendor,const QString & model,const double & factor)1161 void KSUserDB::AddLens(const QString &vendor, const QString &model, const double &factor)
1162 {
1163 m_UserDB.open();
1164 QSqlTableModel equip(nullptr, m_UserDB);
1165 equip.setTable("lens");
1166
1167 int row = 0;
1168 equip.insertRows(row, 1);
1169 equip.setData(equip.index(row, 1), vendor); // row,0 is autoincerement ID
1170 equip.setData(equip.index(row, 2), model);
1171 equip.setData(equip.index(row, 3), factor);
1172 equip.submitAll();
1173
1174 equip.clear();
1175 m_UserDB.close();
1176 }
1177
AddLens(const QString & vendor,const QString & model,const double & factor,const QString & id)1178 void KSUserDB::AddLens(const QString &vendor, const QString &model, const double &factor, const QString &id)
1179 {
1180 m_UserDB.open();
1181 QSqlTableModel equip(nullptr, m_UserDB);
1182 equip.setTable("lens");
1183 equip.setFilter("id = " + id);
1184 equip.select();
1185
1186 if (equip.rowCount() > 0)
1187 {
1188 QSqlRecord record = equip.record(0);
1189 record.setValue(1, vendor);
1190 record.setValue(2, model);
1191 record.setValue(3, factor);
1192 equip.submitAll();
1193 }
1194
1195 m_UserDB.close();
1196 }
1197 #ifndef KSTARS_LITE
GetAllLenses(QList<OAL::Lens * > & lens_list)1198 void KSUserDB::GetAllLenses(QList<OAL::Lens *> &lens_list)
1199 {
1200 lens_list.clear();
1201
1202 m_UserDB.open();
1203 QSqlTableModel equip(nullptr, m_UserDB);
1204 equip.setTable("lens");
1205 equip.select();
1206
1207 for (int i = 0; i < equip.rowCount(); ++i)
1208 {
1209 QSqlRecord record = equip.record(i);
1210 QString id = record.value("id").toString();
1211 QString vendor = record.value("Vendor").toString();
1212 QString model = record.value("Model").toString();
1213 double factor = record.value("Factor").toDouble();
1214 OAL::Lens *o = new OAL::Lens(id, model, vendor, factor);
1215 lens_list.append(o);
1216 }
1217
1218 equip.clear();
1219 m_UserDB.close();
1220 }
1221 #endif
1222 /*
1223 * filter section
1224 */
AddFilter(const QString & vendor,const QString & model,const QString & type,const QString & color,int offset,double exposure,bool useAutoFocus,const QString & lockedFilter,int absFocusPos)1225 void KSUserDB::AddFilter(const QString &vendor, const QString &model, const QString &type, const QString &color,
1226 int offset, double exposure, bool useAutoFocus, const QString &lockedFilter, int absFocusPos)
1227 {
1228 if (m_UserDB.open())
1229 {
1230 QSqlTableModel equip(nullptr, m_UserDB);
1231 equip.setTable("filter");
1232
1233 QSqlRecord record = equip.record();
1234 record.setValue("Vendor", vendor);
1235 record.setValue("Model", model);
1236 record.setValue("Type", type);
1237 record.setValue("Color", color);
1238 record.setValue("Offset", offset);
1239 record.setValue("Exposure", exposure);
1240 record.setValue("UseAutoFocus", useAutoFocus ? 1 : 0);
1241 record.setValue("LockedFilter", lockedFilter);
1242 record.setValue("AbsoluteFocusPosition", absFocusPos);
1243
1244 if (equip.insertRecord(-1, record) == false)
1245 qCritical() << __FUNCTION__ << equip.lastError();
1246
1247
1248 /*int row = 0;
1249 equip.insertRows(row, 1);
1250 equip.setData(equip.index(row, 1), vendor);
1251 equip.setData(equip.index(row, 2), model);
1252 equip.setData(equip.index(row, 3), type);
1253 equip.setData(equip.index(row, 4), offset);
1254 equip.setData(equip.index(row, 5), color);
1255 equip.setData(equip.index(row, 6), exposure);
1256 equip.setData(equip.index(row, 7), lockedFilter);
1257 equip.setData(equip.index(row, 8), useAutoFocus ? 1 : 0);
1258 */
1259 if (equip.submitAll() == false)
1260 qCritical() << "AddFilter:" << equip.lastError();
1261
1262 equip.clear();
1263 m_UserDB.close();
1264 }
1265 else qCritical() << "Failed opening database connection to add filters.";
1266 }
1267
AddFilter(const QString & vendor,const QString & model,const QString & type,const QString & color,int offset,double exposure,bool useAutoFocus,const QString & lockedFilter,int absFocusPos,const QString & id)1268 void KSUserDB::AddFilter(const QString &vendor, const QString &model, const QString &type, const QString &color,
1269 int offset, double exposure, bool useAutoFocus, const QString &lockedFilter, int absFocusPos, const QString &id)
1270 {
1271 m_UserDB.open();
1272 QSqlTableModel equip(nullptr, m_UserDB);
1273 equip.setTable("filter");
1274 equip.setFilter("id = " + id);
1275 equip.select();
1276
1277 if (equip.rowCount() > 0)
1278 {
1279 QSqlRecord record = equip.record(0);
1280 record.setValue("Vendor", vendor);
1281 record.setValue("Model", model);
1282 record.setValue("Type", type);
1283 record.setValue("Color", color);
1284 record.setValue("Offset", offset);
1285 record.setValue("Exposure", exposure);
1286 record.setValue("UseAutoFocus", useAutoFocus ? 1 : 0);
1287 record.setValue("LockedFilter", lockedFilter);
1288 record.setValue("AbsoluteFocusPosition", absFocusPos);
1289 equip.setRecord(0, record);
1290 if (equip.submitAll() == false)
1291 qCritical() << "AddFilter:" << equip.lastError();
1292 }
1293
1294 m_UserDB.close();
1295 }
1296 #ifndef KSTARS_LITE
GetAllFilters(QList<OAL::Filter * > & filter_list)1297 void KSUserDB::GetAllFilters(QList<OAL::Filter *> &filter_list)
1298 {
1299 m_UserDB.open();
1300 filter_list.clear();
1301 QSqlTableModel equip(nullptr, m_UserDB);
1302 equip.setTable("filter");
1303 equip.select();
1304
1305 for (int i = 0; i < equip.rowCount(); ++i)
1306 {
1307 QSqlRecord record = equip.record(i);
1308 QString id = record.value("id").toString();
1309 QString vendor = record.value("Vendor").toString();
1310 QString model = record.value("Model").toString();
1311 QString type = record.value("Type").toString();
1312 QString color = record.value("Color").toString();
1313 int offset = record.value("Offset").toInt();
1314 double exposure = record.value("Exposure").toDouble();
1315 QString lockedFilter = record.value("LockedFilter").toString();
1316 bool useAutoFocus = record.value("UseAutoFocus").toInt() == 1;
1317 int absFocusPos = record.value("AbsoluteFocusPosition").toInt();
1318 OAL::Filter *o = new OAL::Filter(id, model, vendor, type, color, exposure, offset, useAutoFocus, lockedFilter,
1319 absFocusPos);
1320 filter_list.append(o);
1321 }
1322
1323 equip.clear();
1324 m_UserDB.close();
1325 }
1326 #endif
1327 #if 0
1328 bool KSUserDB::ImportFlags()
1329 {
1330 QString flagfilename = QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("flags.dat");
1331 QFile flagsfile(flagfilename);
1332 if (!flagsfile.exists())
1333 {
1334 return false; // No upgrade needed. Flags file doesn't exist.
1335 }
1336
1337 QList< QPair<QString, KSParser::DataTypes> > flag_file_sequence;
1338 flag_file_sequence.append(qMakePair(QString("RA"), KSParser::D_QSTRING));
1339 flag_file_sequence.append(qMakePair(QString("Dec"), KSParser::D_QSTRING));
1340 flag_file_sequence.append(qMakePair(QString("epoch"), KSParser::D_QSTRING));
1341 flag_file_sequence.append(qMakePair(QString("icon"), KSParser::D_QSTRING));
1342 flag_file_sequence.append(qMakePair(QString("label"), KSParser::D_QSTRING));
1343 flag_file_sequence.append(qMakePair(QString("color"), KSParser::D_QSTRING));
1344 KSParser flagparser(flagfilename, '#', flag_file_sequence, ' ');
1345
1346 QHash<QString, QVariant> row_content;
1347 while (flagparser.HasNextRow())
1348 {
1349 row_content = flagparser.ReadNextRow();
1350 QString ra = row_content["RA"].toString();
1351 QString dec = row_content["Dec"].toString();
1352 QString epoch = row_content["epoch"].toString();
1353 QString icon = row_content["icon"].toString();
1354 QString label = row_content["label"].toString();
1355 QString color = row_content["color"].toString();
1356
1357 AddFlag(ra, dec, epoch, icon, label, color);
1358 }
1359 return true;
1360 }
1361
1362 bool KSUserDB::ImportUsers()
1363 {
1364 QString usersfilename = QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("observerlist.xml");
1365 QFile usersfile(usersfilename);
1366
1367 if (!usersfile.exists())
1368 {
1369 return false; // No upgrade needed. Users file doesn't exist.
1370 }
1371
1372 if( ! usersfile.open( QIODevice::ReadOnly ) )
1373 return false;
1374
1375 QXmlStreamReader * reader = new QXmlStreamReader(&usersfile);
1376
1377 while( ! reader->atEnd() )
1378 {
1379 reader->readNext();
1380
1381 if( reader->isEndElement() )
1382 break;
1383
1384 if( reader->isStartElement() )
1385 {
1386 if (reader->name() != "observers")
1387 continue;
1388
1389 //Read all observers
1390 while( ! reader->atEnd() )
1391 {
1392 reader->readNext();
1393
1394 if( reader->isEndElement() )
1395 break;
1396
1397 if( reader->isStartElement() )
1398 {
1399 // Read single observer
1400 if( reader->name() == "observer" )
1401 {
1402 QString name, surname, contact;
1403 while( ! reader->atEnd() )
1404 {
1405 reader->readNext();
1406
1407 if( reader->isEndElement() )
1408 break;
1409
1410 if( reader->isStartElement() )
1411 {
1412 if( reader->name() == "name" )
1413 {
1414 name = reader->readElementText();
1415 }
1416 else if( reader->name() == "surname" )
1417 {
1418 surname = reader->readElementText();
1419 }
1420 else if( reader->name() == "contact" )
1421 {
1422 contact = reader->readElementText();
1423 }
1424 }
1425 }
1426 AddObserver(name, surname, contact);
1427 }
1428 }
1429 }
1430 }
1431 }
1432 delete reader_;
1433 usersfile.close();
1434 return true;
1435 }
1436
1437 bool KSUserDB::ImportEquipment()
1438 {
1439 QString equipfilename = QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("equipmentlist.xml");
1440 QFile equipfile(equipfilename);
1441
1442 if (!equipfile.exists())
1443 {
1444 return false; // No upgrade needed. File doesn't exist.
1445 }
1446
1447 if( ! equipfile.open( QIODevice::ReadOnly ) )
1448 return false;
1449
1450 reader_ = new QXmlStreamReader(&equipfile);
1451 while( ! reader_->atEnd() )
1452 {
1453 reader_->readNext();
1454 if( reader_->isStartElement() )
1455 {
1456 while( ! reader_->atEnd() )
1457 {
1458 reader_->readNext();
1459
1460 if( reader_->isEndElement() )
1461 break;
1462
1463 if( reader_->isStartElement() )
1464 {
1465 if( reader_->name() == "scopes" )
1466 readScopes();
1467 else if( reader_->name() == "eyepieces" )
1468 readEyepieces();
1469 else if( reader_->name() == "lenses" )
1470 readLenses();
1471 else if( reader_->name() == "filters" )
1472 readFilters();
1473 }
1474 }
1475 }
1476 }
1477 delete reader_;
1478 equipfile.close();
1479 return true;
1480 }
1481 #endif
1482
readScopes()1483 void KSUserDB::readScopes()
1484 {
1485 while (!reader_->atEnd())
1486 {
1487 reader_->readNext();
1488
1489 if (reader_->isEndElement())
1490 break;
1491
1492 if (reader_->isStartElement())
1493 {
1494 if (reader_->name() == "scope")
1495 readScope();
1496 }
1497 }
1498 }
1499
readEyepieces()1500 void KSUserDB::readEyepieces()
1501 {
1502 while (!reader_->atEnd())
1503 {
1504 reader_->readNext();
1505
1506 if (reader_->isEndElement())
1507 break;
1508
1509 if (reader_->isStartElement())
1510 {
1511 if (reader_->name() == "eyepiece")
1512 readEyepiece();
1513 }
1514 }
1515 }
1516
readLenses()1517 void KSUserDB::readLenses()
1518 {
1519 while (!reader_->atEnd())
1520 {
1521 reader_->readNext();
1522
1523 if (reader_->isEndElement())
1524 break;
1525
1526 if (reader_->isStartElement())
1527 {
1528 if (reader_->name() == "lens")
1529 readLens();
1530 }
1531 }
1532 }
1533
readFilters()1534 void KSUserDB::readFilters()
1535 {
1536 while (!reader_->atEnd())
1537 {
1538 reader_->readNext();
1539
1540 if (reader_->isEndElement())
1541 break;
1542
1543 if (reader_->isStartElement())
1544 {
1545 if (reader_->name() == "filter")
1546 readFilter();
1547 }
1548 }
1549 }
1550
readScope()1551 void KSUserDB::readScope()
1552 {
1553 QString model, vendor, type, driver = i18nc("No driver", "None");
1554 double aperture = 0, focalLength = 0;
1555
1556 while (!reader_->atEnd())
1557 {
1558 reader_->readNext();
1559
1560 if (reader_->isEndElement())
1561 break;
1562
1563 if (reader_->isStartElement())
1564 {
1565 if (reader_->name() == "model")
1566 {
1567 model = reader_->readElementText();
1568 }
1569 else if (reader_->name() == "vendor")
1570 {
1571 vendor = reader_->readElementText();
1572 }
1573 else if (reader_->name() == "type")
1574 {
1575 type = reader_->readElementText();
1576 if (type == "N")
1577 type = "Newtonian";
1578 if (type == "R")
1579 type = "Refractor";
1580 if (type == "M")
1581 type = "Maksutov";
1582 if (type == "S")
1583 type = "Schmidt-Cassegrain";
1584 if (type == "K")
1585 type = "Kutter (Schiefspiegler)";
1586 if (type == "C")
1587 type = "Cassegrain";
1588 if (type == "RC")
1589 type = "Ritchey-Chretien";
1590 }
1591 else if (reader_->name() == "focalLength")
1592 {
1593 focalLength = (reader_->readElementText()).toDouble();
1594 }
1595 else if (reader_->name() == "aperture")
1596 aperture = (reader_->readElementText()).toDouble();
1597 else if (reader_->name() == "driver")
1598 driver = reader_->readElementText();
1599 }
1600 }
1601
1602 AddScope(model, vendor, driver, type, focalLength, aperture);
1603 }
1604
readEyepiece()1605 void KSUserDB::readEyepiece()
1606 {
1607 QString model, focalLength, vendor, fov, fovUnit;
1608 while (!reader_->atEnd())
1609 {
1610 reader_->readNext();
1611
1612 if (reader_->isEndElement())
1613 break;
1614
1615 if (reader_->isStartElement())
1616 {
1617 if (reader_->name() == "model")
1618 {
1619 model = reader_->readElementText();
1620 }
1621 else if (reader_->name() == "vendor")
1622 {
1623 vendor = reader_->readElementText();
1624 }
1625 else if (reader_->name() == "apparentFOV")
1626 {
1627 fov = reader_->readElementText();
1628 fovUnit = reader_->attributes().value("unit").toString();
1629 }
1630 else if (reader_->name() == "focalLength")
1631 {
1632 focalLength = reader_->readElementText();
1633 }
1634 }
1635 }
1636
1637 AddEyepiece(vendor, model, focalLength.toDouble(), fov.toDouble(), fovUnit);
1638 }
1639
readLens()1640 void KSUserDB::readLens()
1641 {
1642 QString model, factor, vendor;
1643 while (!reader_->atEnd())
1644 {
1645 reader_->readNext();
1646
1647 if (reader_->isEndElement())
1648 break;
1649
1650 if (reader_->isStartElement())
1651 {
1652 if (reader_->name() == "model")
1653 {
1654 model = reader_->readElementText();
1655 }
1656 else if (reader_->name() == "vendor")
1657 {
1658 vendor = reader_->readElementText();
1659 }
1660 else if (reader_->name() == "factor")
1661 {
1662 factor = reader_->readElementText();
1663 }
1664 }
1665 }
1666
1667 AddLens(vendor, model, factor.toDouble());
1668 }
1669
readFilter()1670 void KSUserDB::readFilter()
1671 {
1672 QString model, vendor, type, color, lockedFilter;
1673 int offset = 0;
1674 double exposure = 1.0;
1675 bool useAutoFocus = false;
1676 int absFocusPos = 0;
1677
1678 while (!reader_->atEnd())
1679 {
1680 reader_->readNext();
1681
1682 if (reader_->isEndElement())
1683 break;
1684
1685 if (reader_->isStartElement())
1686 {
1687 if (reader_->name() == "model")
1688 {
1689 model = reader_->readElementText();
1690 }
1691 else if (reader_->name() == "vendor")
1692 {
1693 vendor = reader_->readElementText();
1694 }
1695 else if (reader_->name() == "type")
1696 {
1697 type = reader_->readElementText();
1698 }
1699 else if (reader_->name() == "offset")
1700 {
1701 offset = reader_->readElementText().toInt();
1702 }
1703 else if (reader_->name() == "color")
1704 {
1705 color = reader_->readElementText();
1706 }
1707 else if (reader_->name() == "exposure")
1708 {
1709 exposure = reader_->readElementText().toDouble();
1710 }
1711 else if (reader_->name() == "lockedFilter")
1712 {
1713 lockedFilter = reader_->readElementText();
1714 }
1715 else if (reader_->name() == "useAutoFocus")
1716 {
1717 useAutoFocus = (reader_->readElementText() == "1");
1718 }
1719 else if (reader_->name() == "AbsoluteAutoFocus")
1720 {
1721 absFocusPos = (reader_->readElementText().toInt());
1722 }
1723 }
1724 }
1725 AddFilter(vendor, model, type, color, offset, exposure, useAutoFocus, lockedFilter, absFocusPos);
1726 }
1727
GetAllHorizons()1728 QList<ArtificialHorizonEntity *> KSUserDB::GetAllHorizons()
1729 {
1730 QList<ArtificialHorizonEntity *> horizonList;
1731
1732 m_UserDB.open();
1733 QSqlTableModel regions(nullptr, m_UserDB);
1734 regions.setTable("horizons");
1735 regions.select();
1736
1737 QSqlTableModel points(nullptr, m_UserDB);
1738
1739 for (int i = 0; i < regions.rowCount(); ++i)
1740 {
1741 QSqlRecord record = regions.record(i);
1742 const QString regionTable = record.value("name").toString();
1743 const QString regionName = record.value("label").toString();
1744
1745 const int flags = record.value("enabled").toInt();
1746 const bool enabled = flags & 0x1 ? true : false;
1747 const bool ceiling = flags & 0x2 ? true : false;
1748
1749 points.setTable(regionTable);
1750 points.select();
1751
1752 std::shared_ptr<LineList> skyList(new LineList());
1753
1754 ArtificialHorizonEntity *horizon = new ArtificialHorizonEntity;
1755
1756 horizon->setRegion(regionName);
1757 horizon->setEnabled(enabled);
1758 horizon->setCeiling(ceiling);
1759 horizon->setList(skyList);
1760
1761 horizonList.append(horizon);
1762
1763 for (int j = 0; j < points.rowCount(); j++)
1764 {
1765 std::shared_ptr<SkyPoint> p(new SkyPoint());
1766
1767 record = points.record(j);
1768 p->setAz(record.value(0).toDouble());
1769 p->setAlt(record.value(1).toDouble());
1770 p->HorizontalToEquatorial(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
1771 skyList->append(std::move(p));
1772 }
1773
1774 points.clear();
1775 }
1776
1777 regions.clear();
1778 m_UserDB.close();
1779 return horizonList;
1780 }
1781
DeleteAllHorizons()1782 void KSUserDB::DeleteAllHorizons()
1783 {
1784 m_UserDB.open();
1785 QSqlTableModel regions(nullptr, m_UserDB);
1786 regions.setEditStrategy(QSqlTableModel::OnManualSubmit);
1787 regions.setTable("horizons");
1788 regions.select();
1789
1790 QSqlQuery query(m_UserDB);
1791
1792 for (int i = 0; i < regions.rowCount(); ++i)
1793 {
1794 QSqlRecord record = regions.record(i);
1795 QString tableQuery = QString("DROP TABLE %1").arg(record.value("name").toString());
1796 if (!query.exec(tableQuery))
1797 qCWarning(KSTARS) << query.lastError().text();
1798 }
1799
1800 regions.removeRows(0, regions.rowCount());
1801 regions.submitAll();
1802
1803 regions.clear();
1804 m_UserDB.close();
1805 }
1806
AddHorizon(ArtificialHorizonEntity * horizon)1807 void KSUserDB::AddHorizon(ArtificialHorizonEntity *horizon)
1808 {
1809 m_UserDB.open();
1810 QSqlTableModel regions(nullptr, m_UserDB);
1811 regions.setTable("horizons");
1812
1813 regions.select();
1814 QString tableName = QString("horizon_%1").arg(regions.rowCount() + 1);
1815
1816 regions.insertRow(0);
1817 regions.setData(regions.index(0, 1), tableName);
1818 regions.setData(regions.index(0, 2), horizon->region());
1819 int flags = 0;
1820 if (horizon->enabled()) flags |= 0x1;
1821 if (horizon->ceiling()) flags |= 0x2;
1822 regions.setData(regions.index(0, 3), flags);
1823 regions.submitAll();
1824 regions.clear();
1825
1826 QString tableQuery = QString("CREATE TABLE %1 (Az REAL NOT NULL, Alt REAL NOT NULL)").arg(tableName);
1827 QSqlQuery query(m_UserDB);
1828 query.exec(tableQuery);
1829
1830 QSqlTableModel points(nullptr, m_UserDB);
1831
1832 points.setTable(tableName);
1833
1834 SkyList *skyList = horizon->list()->points();
1835
1836 for (const auto &item : *skyList)
1837 {
1838 points.select();
1839 QSqlRecord rec(points.record());
1840
1841 rec.setValue("Az", item->az().Degrees());
1842 rec.setValue("Alt", item->alt().Degrees());
1843 points.insertRecord(-1, rec);
1844 }
1845
1846 points.submitAll();
1847 points.clear();
1848
1849 m_UserDB.close();
1850 }
1851
AddProfile(const QString & name)1852 int KSUserDB::AddProfile(const QString &name)
1853 {
1854 m_UserDB.open();
1855 int id = -1;
1856
1857 QSqlQuery query(m_UserDB);
1858 bool rc = query.exec(QString("INSERT INTO profile (name) VALUES('%1')").arg(name));
1859
1860 if (rc == false)
1861 qCWarning(KSTARS) << query.lastQuery() << query.lastError().text();
1862 else
1863 id = query.lastInsertId().toInt();
1864
1865 m_UserDB.close();
1866
1867 return id;
1868 }
1869
DeleteProfile(ProfileInfo * pi)1870 bool KSUserDB::DeleteProfile(ProfileInfo *pi)
1871 {
1872 m_UserDB.open();
1873
1874 QSqlQuery query(m_UserDB);
1875 bool rc;
1876
1877 rc = query.exec("DELETE FROM profile WHERE id=" + QString::number(pi->id));
1878
1879 if (rc == false)
1880 qCWarning(KSTARS) << query.lastQuery() << query.lastError().text();
1881
1882 m_UserDB.close();
1883
1884 return rc;
1885 }
1886
SaveProfile(ProfileInfo * pi)1887 void KSUserDB::SaveProfile(ProfileInfo *pi)
1888 {
1889 // Remove all drivers
1890 DeleteProfileDrivers(pi);
1891
1892 m_UserDB.open();
1893 QSqlQuery query(m_UserDB);
1894
1895 // Clear data
1896 if (!query.exec(QString("UPDATE profile SET "
1897 "host=null,port=null,city=null,province=null,country=null,indiwebmanagerport=NULL,"
1898 "autoconnect=NULL,portselector=NULL,primaryscope=0,guidescope=0,indihub=0 WHERE id=%1")
1899 .arg(pi->id)))
1900 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
1901
1902 // Update Name
1903 if (!query.exec(QString("UPDATE profile SET name='%1' WHERE id=%2").arg(pi->name).arg(pi->id)))
1904 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
1905
1906 // Update Remote Data
1907 if (pi->host.isEmpty() == false)
1908 {
1909 if (!query.exec(
1910 QString("UPDATE profile SET host='%1',port=%2 WHERE id=%3").arg(pi->host).arg((pi->port)).arg(pi->id)))
1911 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
1912
1913 if (pi->INDIWebManagerPort != -1)
1914 {
1915 if (!query.exec(QString("UPDATE profile SET indiwebmanagerport='%1' WHERE id=%2")
1916 .arg(pi->INDIWebManagerPort)
1917 .arg(pi->id)))
1918 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
1919 }
1920 }
1921
1922 // Update City Info
1923 if (pi->city.isEmpty() == false)
1924 {
1925 if (!query.exec(QString("UPDATE profile SET city='%1',province='%2',country='%3' WHERE id=%4")
1926 .arg(pi->city, pi->province, pi->country)
1927 .arg(pi->id)))
1928 {
1929 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
1930 }
1931 }
1932
1933 // Update Auto Connect Info
1934 if (!query.exec(QString("UPDATE profile SET autoconnect=%1 WHERE id=%2").arg(pi->autoConnect ? 1 : 0).arg(pi->id)))
1935 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
1936
1937 // Update Port Selector Info
1938 if (!query.exec(QString("UPDATE profile SET portselector=%1 WHERE id=%2").arg(pi->portSelector ? 1 : 0).arg(pi->id)))
1939 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
1940
1941 // Update Guide Application Info
1942 if (!query.exec(QString("UPDATE profile SET guidertype=%1 WHERE id=%2").arg(pi->guidertype).arg(pi->id)))
1943 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
1944
1945 // Update INDI Hub
1946 if (!query.exec(QString("UPDATE profile SET indihub=%1 WHERE id=%2").arg(pi->indihub).arg(pi->id)))
1947 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
1948
1949 // If using external guider
1950 if (pi->guidertype != 0)
1951 {
1952 if (!query.exec(QString("UPDATE profile SET guiderhost='%1' WHERE id=%2").arg(pi->guiderhost).arg(pi->id)))
1953 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
1954 if (!query.exec(QString("UPDATE profile SET guiderport=%1 WHERE id=%2").arg(pi->guiderport).arg(pi->id)))
1955 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
1956 }
1957
1958 // Update scope selection
1959 if (!query.exec(QString("UPDATE profile SET primaryscope='%1' WHERE id=%2").arg(pi->primaryscope).arg(pi->id)))
1960 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
1961 if (!query.exec(QString("UPDATE profile SET guidescope=%1 WHERE id=%2").arg(pi->guidescope).arg(pi->id)))
1962 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
1963
1964 // Update remote drivers
1965 if (!query.exec(QString("UPDATE profile SET remotedrivers='%1' WHERE id=%2").arg(pi->remotedrivers).arg(pi->id)))
1966 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
1967
1968 QMapIterator<QString, QString> i(pi->drivers);
1969 while (i.hasNext())
1970 {
1971 i.next();
1972 if (!query.exec(QString("INSERT INTO driver (label, role, profile) VALUES('%1','%2',%3)")
1973 .arg(i.value(), i.key())
1974 .arg(pi->id)))
1975 {
1976 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
1977 }
1978 }
1979
1980 /*if (pi->customDrivers.isEmpty() == false && !query.exec(QString("INSERT INTO custom_driver (drivers, profile) VALUES('%1',%2)").arg(pi->customDrivers).arg(pi->id)))
1981 qDebug() << query.lastQuery() << query.lastError().text();*/
1982
1983 m_UserDB.close();
1984 }
1985
GetAllProfiles(QList<std::shared_ptr<ProfileInfo>> & profiles)1986 void KSUserDB::GetAllProfiles(QList<std::shared_ptr<ProfileInfo>> &profiles)
1987 {
1988 m_UserDB.open();
1989 QSqlTableModel profile(nullptr, m_UserDB);
1990 profile.setTable("profile");
1991 profile.select();
1992
1993 for (int i = 0; i < profile.rowCount(); ++i)
1994 {
1995 QSqlRecord record = profile.record(i);
1996
1997 int id = record.value("id").toInt();
1998 QString name = record.value("name").toString();
1999 std::shared_ptr<ProfileInfo> pi(new ProfileInfo(id, name));
2000
2001 // Add host and port
2002 pi->host = record.value("host").toString();
2003 pi->port = record.value("port").toInt();
2004
2005 // City info
2006 pi->city = record.value("city").toString();
2007 pi->province = record.value("province").toString();
2008 pi->country = record.value("country").toString();
2009
2010 pi->INDIWebManagerPort = record.value("indiwebmanagerport").toInt();
2011 pi->autoConnect = (record.value("autoconnect").toInt() == 1);
2012 pi->portSelector = (record.value("portselector").toInt() == 1);
2013
2014 pi->indihub = record.value("indihub").toInt();
2015
2016 pi->guidertype = record.value("guidertype").toInt();
2017 if (pi->guidertype != 0)
2018 {
2019 pi->guiderhost = record.value("guiderhost").toString();
2020 pi->guiderport = record.value("guiderport").toInt();
2021 }
2022
2023 pi->primaryscope = record.value("primaryscope").toInt();
2024 pi->guidescope = record.value("guidescope").toInt();
2025
2026 pi->remotedrivers = record.value("remotedrivers").toString();
2027
2028 GetProfileDrivers(pi.get());
2029 //GetProfileCustomDrivers(pi);
2030
2031 profiles.append(pi);
2032 }
2033
2034 profile.clear();
2035 m_UserDB.close();
2036 }
2037
GetProfileDrivers(ProfileInfo * pi)2038 void KSUserDB::GetProfileDrivers(ProfileInfo *pi)
2039 {
2040 m_UserDB.open();
2041
2042 QSqlTableModel driver(nullptr, m_UserDB);
2043 driver.setTable("driver");
2044 driver.setFilter("profile=" + QString::number(pi->id));
2045 if (driver.select() == false)
2046 qCWarning(KSTARS) << "Driver select error:" << driver.lastError().text();
2047
2048 for (int i = 0; i < driver.rowCount(); ++i)
2049 {
2050 QSqlRecord record = driver.record(i);
2051 QString label = record.value("label").toString();
2052 QString role = record.value("role").toString();
2053
2054 pi->drivers[role] = label;
2055 }
2056
2057 driver.clear();
2058 m_UserDB.close();
2059 }
2060
2061 /*void KSUserDB::GetProfileCustomDrivers(ProfileInfo* pi)
2062 {
2063 userdb_.open();
2064 QSqlTableModel custom_driver(0, userdb_);
2065 custom_driver.setTable("driver");
2066 custom_driver.setFilter("profile=" + QString::number(pi->id));
2067 if (custom_driver.select() == false)
2068 qDebug() << "custom driver select error: " << custom_driver.query().lastQuery() << custom_driver.lastError().text();
2069
2070 QSqlRecord record = custom_driver.record(0);
2071 pi->customDrivers = record.value("drivers").toString();
2072
2073 custom_driver.clear();
2074 userdb_.close();
2075 }*/
2076
DeleteProfileDrivers(ProfileInfo * pi)2077 void KSUserDB::DeleteProfileDrivers(ProfileInfo *pi)
2078 {
2079 m_UserDB.open();
2080
2081 QSqlQuery query(m_UserDB);
2082
2083 /*if (!query.exec("DELETE FROM custom_driver WHERE profile=" + QString::number(pi->id)))
2084 qDebug() << query.lastQuery() << query.lastError().text();*/
2085
2086 if (!query.exec("DELETE FROM driver WHERE profile=" + QString::number(pi->id)))
2087 qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2088
2089 m_UserDB.close();
2090 }
2091