Kstars

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

KDE's Doxygen guidelines are available online.