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 #include "oal/dslrlens.h"
15 #include "imageoverlaycomponent.h"
16 
17 #include <QSqlQuery>
18 #include <QSqlRecord>
19 #include <QSqlTableModel>
20 
21 #include <QJsonDocument>
22 
23 #include <kstars_debug.h>
24 
25 /*
26  * TODO (spacetime):
27  * The database supports storing logs. But it needs to be implemented.
28  *
29  * One of the unresolved problems was the creation of a unique identifier
30  * for each object (DSO,planet,star etc) for use in the database.
31 */
32 
33 KSUserDB::~KSUserDB()
34 {
35  // Backup
36  QString current_dbfile = QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath("userdb.sqlite");
37  QString backup_dbfile = QDir(KSPaths::writableLocation(
38  QStandardPaths::AppLocalDataLocation)).filePath("userdb.sqlite.backup");
39  QFile::remove(backup_dbfile);
40  QFile::copy(current_dbfile, backup_dbfile);
41 }
42 
44 {
45  // If the database file does not exist, look for a backup
46  // If the database file exists and is empty, look for a backup
47  // If the database file exists and has data, use it.
48  // If the backup file does not exist, start fresh.
49  // If the backup file exists and has data, replace and use it.
50  // If the database file exists and has no data and the backup file exists, use it.
51  // If the database file exists and has no data and no backup file exists, start fresh.
52 
53  QFileInfo dbfile(QDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath("userdb.sqlite"));
54  QFileInfo backup_file(QDir(KSPaths::writableLocation(
55  QStandardPaths::AppLocalDataLocation)).filePath("userdb.sqlite.backup"));
56 
57  bool const first_run = !dbfile.exists() && !backup_file.exists();
58  m_ConnectionName = dbfile.filePath();
59 
60  // Every logged in user has their own db.
61  auto db = QSqlDatabase::addDatabase("QSQLITE", m_ConnectionName);
62  // This would load the SQLITE file
63  db.setDatabaseName(m_ConnectionName);
64 
65  if (!db.isValid())
66  {
67  qCCritical(KSTARS) << "Unable to prepare database of type sqlite!";
68  return false;
69  }
70 
71  // If main fails to open and we have no backup, fail
72  if (!db.open())
73  {
74  if (!backup_file.exists())
75  {
76  qCCritical(KSTARS) << QString("Failed opening user database '%1'.").arg(dbfile.filePath());
77  qCCritical(KSTARS) << db.lastError();
78  return false;
79  }
80  }
81 
82  // If no main nor backup existed before opening, rebuild
83  if (db.isOpen() && first_run)
84  {
85  qCInfo(KSTARS) << "User DB does not exist. New User DB will be created.";
86  FirstRun();
87  }
88 
89  // If main appears empty/corrupted, restore if possible or rebuild
90  if (db.tables().empty())
91  {
92  if (backup_file.exists())
93  {
94 
95  qCWarning(KSTARS) << "Detected corrupted database. Attempting to recover from backup...";
96  QFile::remove(dbfile.filePath());
97  QFile::copy(backup_file.filePath(), dbfile.filePath());
98  QFile::remove(backup_file.filePath());
99  return Initialize();
100  }
101  else if (!FirstRun())
102  {
103  qCCritical(KSTARS) << QString("Failed initializing user database '%1.").arg(dbfile.filePath());
104  return false;
105  }
106  }
107 
108  qCDebug(KSTARS) << "Opened the User DB. Ready.";
109 
110  // Update table if previous version exists
111  QSqlTableModel version(nullptr, db);
112  version.setTable("Version");
113  version.select();
114  QSqlRecord record = version.record(0);
115  version.clear();
116 
117  // Old version had 2.9.5 ..etc, so we remove them
118  // Starting with 2.9.7, we are using SCHEMA_VERSION which now decoupled from KStars Version and starts at 300
119  int currentDBVersion = record.value("Version").toString().remove(".").toInt();
120 
121  // Update database version to current KStars version
122  if (currentDBVersion != SCHEMA_VERSION)
123  {
124  QSqlQuery query(db);
125  QString versionQuery = QString("UPDATE Version SET Version=%1").arg(SCHEMA_VERSION);
126  if (!query.exec(versionQuery))
127  qCWarning(KSTARS) << query.lastError();
128  }
129 
130  // If prior to 2.9.4 extend filters table
131  if (currentDBVersion < 294)
132  {
133  QSqlQuery query(db);
134 
135  qCWarning(KSTARS) << "Detected old format filter table, re-creating...";
136  if (!query.exec("DROP table filter"))
137  qCWarning(KSTARS) << query.lastError();
138  if (!query.exec("CREATE TABLE filter ( "
139  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
140  "Vendor TEXT DEFAULT NULL, "
141  "Model TEXT DEFAULT NULL, "
142  "Type TEXT DEFAULT NULL, "
143  "Color TEXT DEFAULT NULL,"
144  "Exposure REAL DEFAULT 1.0,"
145  "Offset INTEGER DEFAULT 0,"
146  "UseAutoFocus INTEGER DEFAULT 0,"
147  "LockedFilter TEXT DEFAULT '--',"
148  "AbsoluteFocusPosition INTEGER DEFAULT 0)"))
149  qCWarning(KSTARS) << query.lastError();
150  }
151 
152  // If prior to 2.9.5 create fov table
153  if (currentDBVersion < 295)
154  {
155  QSqlQuery query(db);
156 
157  if (!query.exec("CREATE TABLE effectivefov ( "
158  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
159  "Profile TEXT DEFAULT NULL, "
160  "Width INTEGER DEFAULT NULL, "
161  "Height INTEGER DEFAULT NULL, "
162  "PixelW REAL DEFAULT 5.0,"
163  "PixelH REAL DEFAULT 5.0,"
164  "FocalLength REAL DEFAULT 0.0,"
165  "FovW REAL DEFAULT 0.0,"
166  "FovH REAL DEFAULT 0.0)"))
167  qCWarning(KSTARS) << query.lastError();
168  }
169 
170  if (currentDBVersion < 300)
171  {
172  QSqlQuery query(db);
173  QString columnQuery = QString("ALTER TABLE profile ADD COLUMN remotedrivers TEXT DEFAULT NULL");
174  if (!query.exec(columnQuery))
175  qCWarning(KSTARS) << query.lastError();
176 
177  if (db.tables().contains("customdrivers") == false)
178  {
179  if (!query.exec("CREATE TABLE customdrivers ( "
180  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
181  "Name TEXT DEFAULT NULL, "
182  "Label TEXT DEFAULT NULL UNIQUE, "
183  "Manufacturer TEXT DEFAULT NULL, "
184  "Family TEXT DEFAULT NULL, "
185  "Exec TEXT DEFAULT NULL, "
186  "Version TEXT DEFAULT 1.0)"))
187  qCWarning(KSTARS) << query.lastError();
188  }
189  }
190 
191  // Add manufacturer
192  if (currentDBVersion < 305)
193  {
194  QSqlQuery query(db);
195  QString columnQuery = QString("ALTER TABLE customdrivers ADD COLUMN Manufacturer TEXT DEFAULT NULL");
196  if (!query.exec(columnQuery))
197  qCWarning(KSTARS) << query.lastError();
198  }
199 
200  // Add indihub
201  if (currentDBVersion < 306)
202  {
203  QSqlQuery query(db);
204  QString columnQuery = QString("ALTER TABLE profile ADD COLUMN indihub INTEGER DEFAULT 0");
205  if (!query.exec(columnQuery))
206  qCWarning(KSTARS) << query.lastError();
207  }
208 
209  // Add Defect Map
210  if (currentDBVersion < 307)
211  {
212  QSqlQuery query(db);
213  // If we are upgrading, remove all previous entries.
214  QString clearQuery = QString("DELETE FROM darkframe");
215  if (!query.exec(clearQuery))
216  qCWarning(KSTARS) << query.lastError();
217  QString columnQuery = QString("ALTER TABLE darkframe ADD COLUMN defectmap TEXT DEFAULT NULL");
218  if (!query.exec(columnQuery))
219  qCWarning(KSTARS) << query.lastError();
220  }
221 
222  // Add port selector
223  if (currentDBVersion < 308)
224  {
225  QSqlQuery query(db);
226  QString columnQuery = QString("ALTER TABLE profile ADD COLUMN portselector INTEGER DEFAULT 0");
227  if (!query.exec(columnQuery))
228  qCWarning(KSTARS) << query.lastError();
229  }
230 
231  // Add Gain/ISO to Dark Library
232  if (currentDBVersion < 309)
233  {
234  QSqlQuery query(db);
235  QString columnQuery = QString("ALTER TABLE darkframe ADD COLUMN gain INTEGER DEFAULT -1");
236  if (!query.exec(columnQuery))
237  qCWarning(KSTARS) << query.lastError();
238  columnQuery = QString("ALTER TABLE darkframe ADD COLUMN iso TEXT DEFAULT NULL");
239  if (!query.exec(columnQuery))
240  qCWarning(KSTARS) << query.lastError();
241  }
242 
243  // Add scripts to profile
244  if (currentDBVersion < 310)
245  {
246  QSqlQuery query(db);
247  QString columnQuery = QString("ALTER TABLE profile ADD COLUMN scripts TEXT DEFAULT NULL");
248  if (!query.exec(columnQuery))
249  qCWarning(KSTARS) << query.lastError();
250  }
251 
252  // Add optical trains
253  if (currentDBVersion < 311)
254  {
255  QSqlQuery query(db);
256  if (!query.exec("CREATE TABLE opticaltrains ( "
257  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
258  "profile INTEGER DEFAULT NULL, "
259  "name TEXT DEFAULT NULL, "
260  "mount TEXT DEFAULT NULL, "
261  "dustcap TEXT DEFAULT NULL, "
262  "lightbox TEXT DEFAULT NULL, "
263  "scope TEXT DEFAULT NULL, "
264  "reducer REAL DEFAULT 1, "
265  "rotator TEXT DEFAULT NULL, "
266  "focuser TEXT DEFAULT NULL, "
267  "filterwheel TEXT DEFAULT NULL, "
268  "camera TEXT DEFAULT NULL, "
269  "guider TEXT DEFAULT NULL)"))
270  qCWarning(KSTARS) << query.lastError();
271 
272  if (!query.exec("CREATE TABLE profilesettings ( "
273  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
274  "profile INTEGER DEFAULT NULL, "
275  "settings TEXT DEFAULT NULL)"))
276  qCWarning(KSTARS) << query.lastError();
277 
278  if (!query.exec("CREATE TABLE opticaltrainsettings ( "
279  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
280  "opticaltrain INTEGER DEFAULT NULL, "
281  "settings TEXT DEFAULT NULL)"))
282  qCWarning(KSTARS) << query.lastError();
283 
284 
285  // Add DSLR lenses table
286  if (!query.exec("CREATE TABLE dslrlens ( "
287  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
288  "Vendor TEXT DEFAULT NULL, "
289  "Model TEXT DEFAULT NULL, "
290  "FocalLength REAL DEFAULT NULL, "
291  "FocalRatio REAL DEFAULT NULL)"))
292  qCWarning(KSTARS) << query.lastError();
293 
294  // Need to offset primary key by 100,000 to differential it from scopes and keep it backward compatible.
295  if (!query.exec("UPDATE SQLITE_SEQUENCE SET seq = 100000 WHERE name ='dslrlens'"))
296  qCWarning(KSTARS) << query.lastError();
297  }
298 
299  // Adjust effective FOV
300  if (currentDBVersion < 312)
301  {
302  QSqlQuery query(db);
303 
304  if (!query.exec("ALTER TABLE effectivefov ADD COLUMN Train TEXT DEFAULT NULL"))
305  qCWarning(KSTARS) << query.lastError();
306  if (!query.exec("ALTER TABLE effectivefov ADD COLUMN FocalReducer REAL DEFAULT 0.0"))
307  qCWarning(KSTARS) << query.lastError();
308  if (!query.exec("ALTER TABLE effectivefov ADD COLUMN FocalRatio REAL DEFAULT 0.0"))
309  qCWarning(KSTARS) << query.lastError();
310  }
311 
312  // Add focusTemperature, focusAltitude, focusTicksPerTemp, focusTicksPerAlt and wavelength to filter table
313  if (currentDBVersion < 313)
314  {
315  QSqlQuery query(db);
316 
317  if (!query.exec("ALTER TABLE filter ADD COLUMN FocusTemperature REAL DEFAULT NULL"))
318  qCWarning(KSTARS) << query.lastError();
319  if (!query.exec("ALTER TABLE filter ADD COLUMN FocusAltitude REAL DEFAULT NULL"))
320  qCWarning(KSTARS) << query.lastError();
321  if (!query.exec("ALTER TABLE filter ADD COLUMN FocusTicksPerTemp REAL DEFAULT 0.0"))
322  qCWarning(KSTARS) << query.lastError();
323  if (!query.exec("ALTER TABLE filter ADD COLUMN FocusTicksPerAlt REAL DEFAULT 0.0"))
324  qCWarning(KSTARS) << query.lastError();
325  if (!query.exec("ALTER TABLE filter ADD COLUMN Wavelength REAL DEFAULT 500.0"))
326  qCWarning(KSTARS) << query.lastError();
327  }
328 
329 
330  return true;
331 }
332 
333 ////////////////////////////////////////////////////////////////////////////////////////////////////////
334 ///
335 ////////////////////////////////////////////////////////////////////////////////////////////////////////
336 bool KSUserDB::FirstRun()
337 {
338  if (!RebuildDB())
339  return false;
340  return true;
341 }
342 
343 ////////////////////////////////////////////////////////////////////////////////////////////////////////
344 ///
345 ////////////////////////////////////////////////////////////////////////////////////////////////////////
346 bool KSUserDB::RebuildDB()
347 {
348  auto db = QSqlDatabase::database(m_ConnectionName);
349  qCInfo(KSTARS) << "Rebuilding User Database";
350 
351  QVector<QString> tables;
352  tables.append("CREATE TABLE Version ("
353  "Version CHAR DEFAULT NULL)");
354  tables.append("INSERT INTO Version VALUES (\"" KSTARS_VERSION "\")");
355  tables.append("CREATE TABLE user ( "
356  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
357  "Name TEXT NOT NULL DEFAULT 'NULL', "
358  "Surname TEXT NOT NULL DEFAULT 'NULL', "
359  "Contact TEXT DEFAULT NULL)");
360 
361  tables.append("CREATE TABLE telescope ( "
362  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
363  "Vendor TEXT DEFAULT NULL, "
364  "Aperture REAL NOT NULL DEFAULT NULL, "
365  "Model TEXT DEFAULT NULL, "
366  "Type TEXT DEFAULT NULL, "
367  "FocalLength REAL DEFAULT NULL)");
368 
369  tables.append("INSERT INTO telescope (Vendor, Aperture, Model, Type, FocalLength) VALUES "
370  "('Sample', 120, 'Primary', 'Refractor', 700)");
371 
372  tables.append("INSERT INTO telescope (Vendor, Aperture, Model, Type, FocalLength) VALUES "
373  "('Sample', 50, 'Guide', 'Refractor', 300)");
374 
375  tables.append("CREATE TABLE flags ( "
376  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
377  "RA TEXT NOT NULL DEFAULT NULL, "
378  "Dec TEXT NOT NULL DEFAULT NULL, "
379  "Icon TEXT NOT NULL DEFAULT 'NULL', "
380  "Label TEXT NOT NULL DEFAULT 'NULL', "
381  "Color TEXT DEFAULT NULL, "
382  "Epoch TEXT DEFAULT NULL)");
383 
384  tables.append("CREATE TABLE lens ( "
385  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
386  "Vendor TEXT NOT NULL DEFAULT 'NULL', "
387  "Model TEXT DEFAULT NULL, "
388  "Factor REAL NOT NULL DEFAULT NULL)");
389 
390  tables.append("CREATE TABLE dslrlens ( "
391  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
392  "Vendor TEXT DEFAULT NULL, "
393  "Model TEXT DEFAULT NULL, "
394  "FocalLength REAL DEFAULT NULL, "
395  "FocalRatio REAL DEFAULT NULL)");
396 
397  tables.append("CREATE TABLE eyepiece ( "
398  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
399  "Vendor TEXT DEFAULT NULL, "
400  "Model TEXT DEFAULT NULL, "
401  "FocalLength REAL NOT NULL DEFAULT NULL, "
402  "ApparentFOV REAL NOT NULL DEFAULT NULL, "
403  "FOVUnit TEXT NOT NULL DEFAULT NULL)");
404 
405  tables.append("CREATE TABLE filter ( "
406  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
407  "Vendor TEXT DEFAULT NULL, "
408  "Model TEXT DEFAULT NULL, "
409  "Type TEXT DEFAULT NULL, "
410  "Color TEXT DEFAULT NULL,"
411  "Exposure REAL DEFAULT 1.0,"
412  "Offset INTEGER DEFAULT 0,"
413  "UseAutoFocus INTEGER DEFAULT 0,"
414  "LockedFilter TEXT DEFAULT '--',"
415  "AbsoluteFocusPosition INTEGER DEFAULT 0,"
416  "FocusTemperature REAL DEFAULT NULL,"
417  "FocusAltitude REAL DEFAULT NULL,"
418  "FocusTicksPerTemp REAL DEFAULT 0.0,"
419  "FocusTicksPerAlt REAL DEFAULT 0.0,"
420  "Wavelength INTEGER DEFAULT 500)");
421 
422  tables.append("CREATE TABLE wishlist ( "
423  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
424  "Date NUMERIC NOT NULL DEFAULT NULL, "
425  "Type TEXT DEFAULT NULL, "
426  "UIUD TEXT DEFAULT NULL)");
427 
428  tables.append("CREATE TABLE fov ( "
429  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
430  "name TEXT NOT NULL DEFAULT 'NULL', "
431  "color TEXT DEFAULT NULL, "
432  "sizeX NUMERIC DEFAULT NULL, "
433  "sizeY NUMERIC DEFAULT NULL, "
434  "shape TEXT DEFAULT NULL)");
435 
436  tables.append("CREATE TABLE logentry ( "
437  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
438  "content TEXT NOT NULL DEFAULT 'NULL', "
439  "UIUD TEXT DEFAULT NULL, "
440  "DateTime NUMERIC NOT NULL DEFAULT NULL, "
441  "User INTEGER DEFAULT NULL REFERENCES user (id), "
442  "Location TEXT DEFAULT NULL, "
443  "Telescope INTEGER DEFAULT NULL REFERENCES telescope (id),"
444  "Filter INTEGER DEFAULT NULL REFERENCES filter (id), "
445  "lens INTEGER DEFAULT NULL REFERENCES lens (id), "
446  "Eyepiece INTEGER DEFAULT NULL REFERENCES eyepiece (id), "
447  "FOV INTEGER DEFAULT NULL REFERENCES fov (id))");
448 
449  // Note: enabled now encodes both a bool enabled value as well
450  // as another bool indicating if this is a horizon line or a ceiling line.
451  tables.append("CREATE TABLE horizons ( "
452  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
453  "name TEXT NOT NULL,"
454  "label TEXT NOT NULL,"
455  "enabled INTEGER NOT NULL)");
456 
457  tables.append("CREATE TABLE profile (id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, host "
458  "TEXT, port INTEGER, city TEXT, province TEXT, country TEXT, indiwebmanagerport INTEGER DEFAULT "
459  "NULL, autoconnect INTEGER DEFAULT 1, guidertype INTEGER DEFAULT 0, guiderhost TEXT, guiderport INTEGER,"
460  "indihub INTEGER DEFAULT 0, portselector INTEGER DEFAULT 1, remotedrivers TEXT DEFAULT NULL, "
461  "scripts TEXT DEFAULT NULL)");
462 
463 #ifdef Q_OS_WIN
464  tables.append("INSERT INTO profile (name, host, port) VALUES ('Simulators', 'localhost', 7624)");
465 #else
466  tables.append("INSERT INTO profile (name, portselector) VALUES ('Simulators', 0)");
467 #endif
468 
469  tables.append("CREATE TABLE driver (id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, label TEXT NOT NULL, role "
470  "TEXT NOT NULL, profile INTEGER NOT NULL, FOREIGN KEY(profile) REFERENCES profile(id))");
471  //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))");
472 
473  tables.append("INSERT INTO driver (label, role, profile) VALUES ('Telescope Simulator', 'Mount', 1)");
474  tables.append("INSERT INTO driver (label, role, profile) VALUES ('CCD Simulator', 'CCD', 1)");
475  tables.append("INSERT INTO driver (label, role, profile) VALUES ('Focuser Simulator', 'Focuser', 1)");
476 
477  tables.append("CREATE TABLE profilesettings (id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
478  "profile INTEGER DEFAULT NULL, settings TEXT DEFAULT NULL)");
479 
480  tables.append("CREATE TABLE opticaltrains (id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
481  "profile INTEGER DEFAULT NULL, name TEXT DEFAULT NULL, mount TEXT DEFAULT NULL, "
482  "dustcap TEXT DEFAULT NULL, lightbox TEXT DEFAULT NULL, scope TEXT DEFAULT NULL, reducer REAL DEFAULT 1, "
483  "rotator TEXT DEFAULT NULL, focuser TEXT DEFAULT NULL, filterwheel TEXT DEFAULT NULL, camera TEXT DEFAULT NULL, "
484  "guider TEXT DEFAULT NULL)");
485 
486  tables.append("CREATE TABLE opticaltrainsettings (id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
487  "opticaltrain INTEGER DEFAULT NULL, settings TEXT DEFAULT NULL)");
488 
489  tables.append("CREATE TABLE IF NOT EXISTS darkframe (id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, ccd TEXT "
490  "NOT NULL, chip INTEGER DEFAULT 0, binX INTEGER, binY INTEGER, temperature REAL, gain INTEGER DEFAULT -1, "
491  "iso TEXT DEFAULT NULL, duration REAL, filename TEXT NOT NULL, defectmap TEXT DEFAULT NULL, timestamp "
492  "DATETIME DEFAULT CURRENT_TIMESTAMP)");
493 
494  tables.append("CREATE TABLE IF NOT EXISTS hips (ID TEXT NOT NULL UNIQUE,"
495  "obs_title TEXT NOT NULL, obs_description TEXT NOT NULL, hips_order TEXT NOT NULL,"
496  "hips_frame TEXT NOT NULL, hips_tile_width TEXT NOT NULL, hips_tile_format TEXT NOT NULL,"
497  "hips_service_url TEXT NOT NULL, moc_sky_fraction TEXT NOT NULL)");
498 
499  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)"
500  "VALUES ('CDS/P/DSS2/color', 'DSS Colored', 'Color composition generated by CDS. This HiPS survey is based on 2 others HiPS surveys,"
501  " respectively DSS2-red and DSS2-blue HiPS, both of them directly generated from original scanned plates downloaded"
502  " from STScI site. The red component has been built from POSS-II F, AAO-SES,SR and SERC-ER plates. The blue component"
503  " has been build from POSS-II J and SERC-J,EJ. The green component is based on the mean of other components. Three"
504  " missing plates from red survey (253, 260, 359) has been replaced by pixels from the DSSColor STScI jpeg survey."
505  " The 11 missing blue plates (mainly in galactic plane) have not been replaced (only red component).',"
506  "'9', 'equatorial', '512', 'jpeg fits', 'http://alasky.u-strasbg.fr/DSS/DSSColor','1')");
507 
508  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)"
509  "VALUES ('CDS/P/2MASS/color', '2MASS Color J (1.23 microns), H (1.66 microns), K (2.16 microns)',"
510  "'2MASS has uniformly scanned the entire sky in three near-infrared bands to detect and characterize point sources"
511  " brighter than about 1 mJy in each band, with signal-to-noise ratio (SNR) greater than 10, using a pixel size of"
512  " 2.0\". This has achieved an 80,000-fold improvement in sensitivity relative to earlier surveys. 2MASS used two"
513  " highly-automated 1.3-m telescopes, one at Mt. Hopkins, AZ, and one at CTIO, Chile. Each telescope was equipped with"
514  " a three-channel camera, each channel consisting of a 256x256 array of HgCdTe detectors, capable of observing the"
515  " sky simultaneously at J (1.25 microns), H (1.65 microns), and Ks (2.17 microns). The University of Massachusetts"
516  " (UMass) was responsible for the overall management of the project, and for developing the infrared cameras and"
517  " on-site computing systems at both facilities. The Infrared Processing and Analysis Center (IPAC) is responsible"
518  " for all data processing through the Production Pipeline, and construction and distribution of the data products."
519  " Funding is provided primarily by NASA and the NSF',"
520  "'9', 'equatorial', '512', 'jpeg fits', 'http://alaskybis.u-strasbg.fr/2MASS/Color', '1')");
521 
522  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)"
523  "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"
524  " highest-energy form of light. This survey sums all data observed by the Fermi mission up to week 396. This version"
525  " of the Fermi survey are intensity maps where the summed counts maps are divided by the exposure for each pixel"
526  ". We anticipate using the HEASARC Hera capabilities to update this survey on a roughly quarterly basis. Data is"
527  " 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 ,"
528  " 3-300 GeV Band 5. The SkyView data are based upon a Cartesian projection of the counts divided by the exposure maps."
529  " In the Cartesian projection pixels near the pole have a much smaller area than pixels on the equator, so these"
530  " pixels have smaller integrated flux. When creating large scale images in other projections users may wish to make"
531  " sure to compensate for this effect the flux conserving clip-resampling option.', '9', 'equatorial', '512', 'jpeg fits',"
532  "'http://alaskybis.u-strasbg.fr/Fermi/Color', '1')");
533 
534 
535  tables.append("CREATE TABLE dslr (id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
536  "Model TEXT DEFAULT NULL, "
537  "Width INTEGER DEFAULT NULL, "
538  "Height INTEGER DEFAULT NULL, "
539  "PixelW REAL DEFAULT 5.0,"
540  "PixelH REAL DEFAULT 5.0)");
541 
542 
543  tables.append("CREATE TABLE effectivefov ( "
544  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
545  "Train TEXT DEFAULT NULL, "
546  "Profile TEXT DEFAULT NULL, "
547  "Width INTEGER DEFAULT NULL, "
548  "Height INTEGER DEFAULT NULL, "
549  "PixelW REAL DEFAULT 5.0,"
550  "PixelH REAL DEFAULT 5.0,"
551  "FocalLength REAL DEFAULT 0.0,"
552  "FocalReducer REAL DEFAULT 0.0,"
553  "FocalRatio REAL DEFAULT 0.0,"
554  "FovW REAL DEFAULT 0.0,"
555  "FovH REAL DEFAULT 0.0)");
556 
557  tables.append("CREATE TABLE customdrivers ( "
558  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
559  "Name TEXT DEFAULT NULL, "
560  "Label TEXT DEFAULT NULL UNIQUE, "
561  "Manufacturer TEXT DEFAULT NULL, "
562  "Family TEXT DEFAULT NULL, "
563  "Exec TEXT DEFAULT NULL, "
564  "Version TEXT DEFAULT 1.0)");
565 
566  // Need to offset primary key by 100,000 to differential it from scopes and keep it backward compatible.
567  tables.append("UPDATE SQLITE_SEQUENCE SET seq = 100000 WHERE name ='dslrlens'");
568 
569  for (int i = 0; i < tables.count(); ++i)
570  {
571  QSqlQuery query(db);
572  if (!query.exec(tables[i]))
573  {
574  qCDebug(KSTARS) << query.lastError();
575  qCDebug(KSTARS) << query.executedQuery();
576  }
577  }
578 
579  return true;
580 }
581 
582 /*
583  * Observer Section
584 */
585 
586 ////////////////////////////////////////////////////////////////////////////////////////////////////////
587 ///
588 ////////////////////////////////////////////////////////////////////////////////////////////////////////
589 bool KSUserDB::AddObserver(const QString &name, const QString &surname, const QString &contact)
590 {
591  auto db = QSqlDatabase::database(m_ConnectionName);
592  if (!db.isValid())
593  {
594  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
595  return false;
596  }
597 
598  QSqlTableModel users(nullptr, db);
599  users.setTable("user");
600  users.setFilter("Name LIKE \'" + name + "\' AND Surname LIKE \'" + surname + "\'");
601  users.select();
602 
603  if (users.rowCount() > 0)
604  {
605  QSqlRecord record = users.record(0);
606  record.setValue("Name", name);
607  record.setValue("Surname", surname);
608  record.setValue("Contact", contact);
609  users.setRecord(0, record);
610  users.submitAll();
611  }
612  else
613  {
614  int row = 0;
615  users.insertRows(row, 1);
616  users.setData(users.index(row, 1), name); // row0 is autoincerement ID
617  users.setData(users.index(row, 2), surname);
618  users.setData(users.index(row, 3), contact);
619  users.submitAll();
620  }
621 
622  return true;
623 }
624 
625 ////////////////////////////////////////////////////////////////////////////////////////////////////////
626 ///
627 ////////////////////////////////////////////////////////////////////////////////////////////////////////
628 bool KSUserDB::FindObserver(const QString &name, const QString &surname)
629 {
630  auto db = QSqlDatabase::database(m_ConnectionName);
631  if (!db.isValid())
632  {
633  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
634  return false;
635  }
636 
637  QSqlTableModel users(nullptr, db);
638  users.setTable("user");
639  users.setFilter("Name LIKE \'" + name + "\' AND Surname LIKE \'" + surname + "\'");
640  users.select();
641 
642  int observer_count = users.rowCount();
643 
644  users.clear();
645  return (observer_count > 0);
646 }
647 
648 ////////////////////////////////////////////////////////////////////////////////////////////////////////
649 ///
650 ////////////////////////////////////////////////////////////////////////////////////////////////////////
652 {
653  auto db = QSqlDatabase::database(m_ConnectionName);
654  if (!db.isValid())
655  {
656  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
657  return false;
658  }
659 
660  QSqlTableModel users(nullptr, db);
661  users.setTable("user");
662  users.setFilter("id = \'" + id + "\'");
663  users.select();
664 
665  users.removeRows(0, 1);
666  users.submitAll();
667 
668  int observer_count = users.rowCount();
669 
670  users.clear();
671  return (observer_count > 0);
672 }
673 
674 #ifndef KSTARS_LITE
675 ////////////////////////////////////////////////////////////////////////////////////////////////////////
676 ///
677 ////////////////////////////////////////////////////////////////////////////////////////////////////////
679 {
680  auto db = QSqlDatabase::database(m_ConnectionName);
681  if (!db.isValid())
682  {
683  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
684  return false;
685  }
686 
687  observer_list.clear();
688  QSqlTableModel users(nullptr, db);
689  users.setTable("user");
690  users.select();
691 
692  for (int i = 0; i < users.rowCount(); ++i)
693  {
694  QSqlRecord record = users.record(i);
695  QString id = record.value("id").toString();
696  QString name = record.value("Name").toString();
697  QString surname = record.value("Surname").toString();
698  QString contact = record.value("Contact").toString();
699  OAL::Observer *o = new OAL::Observer(id, name, surname, contact);
700  observer_list.append(o);
701  }
702 
703  users.clear();
704  return true;
705 }
706 #endif
707 
708 /* Dark Library Section */
709 
710 /**
711  * @brief KSUserDB::AddDarkFrame Saves a new dark frame data to the database
712  * @param oneFrame Map that contains 1 to 1 correspondence with the database table, except for primary key and timestamp.
713  */
714 bool KSUserDB::AddDarkFrame(const QVariantMap &oneFrame)
715 {
716  auto db = QSqlDatabase::database(m_ConnectionName);
717  if (!db.isValid())
718  {
719  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
720  return false;
721  }
722 
723  QSqlTableModel darkframe(nullptr, db);
724  darkframe.setTable("darkframe");
725  darkframe.select();
726 
727  QSqlRecord record = darkframe.record();
728  // Remove PK so that it gets auto-incremented later
729  record.remove(0);
730 
731  for (QVariantMap::const_iterator iter = oneFrame.begin(); iter != oneFrame.end(); ++iter)
732  record.setValue(iter.key(), iter.value());
733 
734  darkframe.insertRecord(-1, record);
735  darkframe.submitAll();
736  return true;
737 }
738 
739 /**
740  * @brief KSUserDB::UpdateDarkFrame Updates an existing dark frame record in the data, replace all values matching the supplied ID
741  * @param oneFrame dark frame to update. The ID should already exist in the database.
742  */
743 bool KSUserDB::UpdateDarkFrame(const QVariantMap &oneFrame)
744 {
745  auto db = QSqlDatabase::database(m_ConnectionName);
746  if (!db.isValid())
747  {
748  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
749  return false;
750  }
751 
752  QSqlTableModel darkframe(nullptr, db);
753  darkframe.setTable("darkframe");
754  darkframe.setFilter(QString("id=%1").arg(oneFrame["id"].toInt()));
755  darkframe.select();
756 
757  QSqlRecord record = darkframe.record(0);
758  for (QVariantMap::const_iterator iter = oneFrame.begin(); iter != oneFrame.end(); ++iter)
759  record.setValue(iter.key(), iter.value());
760 
761  darkframe.setRecord(0, record);
762  darkframe.submitAll();
763 
764  return true;
765 }
766 
767 /**
768  * @brief KSUserDB::DeleteDarkFrame Delete from database a dark frame record that matches the filename field.
769  * @param filename filename of dark frame to delete from database.
770  */
771 bool KSUserDB::DeleteDarkFrame(const QString &filename)
772 {
773  auto db = QSqlDatabase::database(m_ConnectionName);
774  if (!db.isValid())
775  {
776  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
777  return false;
778  }
779 
780  QSqlTableModel darkframe(nullptr, db);
781  darkframe.setTable("darkframe");
782  darkframe.setFilter("filename = \'" + filename + "\'");
783 
784  darkframe.select();
785 
786  darkframe.removeRows(0, 1);
787  darkframe.submitAll();
788 
789  return true;
790 }
791 
792 ////////////////////////////////////////////////////////////////////////////////////////////////////////
793 ///
794 ////////////////////////////////////////////////////////////////////////////////////////////////////////
795 bool KSUserDB::GetAllDarkFrames(QList<QVariantMap> &darkFrames)
796 {
797  auto db = QSqlDatabase::database(m_ConnectionName);
798  if (!db.isValid())
799  {
800  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
801  return false;
802  }
803 
804  darkFrames.clear();
805 
806  QSqlTableModel darkframe(nullptr, db);
807  darkframe.setTable("darkframe");
808  darkframe.select();
809 
810  for (int i = 0; i < darkframe.rowCount(); ++i)
811  {
812  QVariantMap recordMap;
813  QSqlRecord record = darkframe.record(i);
814  for (int j = 0; j < record.count(); j++)
815  recordMap[record.fieldName(j)] = record.value(j);
816 
817  darkFrames.append(recordMap);
818  }
819 
820  return true;
821 }
822 
823 
824 /* Effective FOV Section */
825 
826 ////////////////////////////////////////////////////////////////////////////////////////////////////////
827 ///
828 ////////////////////////////////////////////////////////////////////////////////////////////////////////
829 bool KSUserDB::AddEffectiveFOV(const QVariantMap &oneFOV)
830 {
831  auto db = QSqlDatabase::database(m_ConnectionName);
832  if (!db.isValid())
833  {
834  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
835  return false;
836  }
837 
838  QSqlTableModel effectivefov(nullptr, db);
839  effectivefov.setTable("effectivefov");
840  effectivefov.select();
841 
842  QSqlRecord record = effectivefov.record();
843 
844  // Remove PK so that it gets auto-incremented later
845  record.remove(0);
846 
847  for (QVariantMap::const_iterator iter = oneFOV.begin(); iter != oneFOV.end(); ++iter)
848  record.setValue(iter.key(), iter.value());
849 
850  effectivefov.insertRecord(-1, record);
851 
852  effectivefov.submitAll();
853 
854  return true;
855 }
856 
857 ////////////////////////////////////////////////////////////////////////////////////////////////////////
858 ///
859 ////////////////////////////////////////////////////////////////////////////////////////////////////////
860 bool KSUserDB::DeleteEffectiveFOV(const QString &id)
861 {
862  auto db = QSqlDatabase::database(m_ConnectionName);
863  if (!db.isValid())
864  {
865  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
866  return false;
867  }
868 
869  QSqlTableModel effectivefov(nullptr, db);
870  effectivefov.setTable("effectivefov");
871  effectivefov.setFilter("id = \'" + id + "\'");
872 
873  effectivefov.select();
874 
875  effectivefov.removeRows(0, 1);
876  effectivefov.submitAll();
877  return true;
878 }
879 
880 ////////////////////////////////////////////////////////////////////////////////////////////////////////
881 ///
882 ////////////////////////////////////////////////////////////////////////////////////////////////////////
883 bool KSUserDB::GetAllEffectiveFOVs(QList<QVariantMap> &effectiveFOVs)
884 {
885  auto db = QSqlDatabase::database(m_ConnectionName);
886  if (!db.isValid())
887  {
888  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
889  return false;
890  }
891 
892  effectiveFOVs.clear();
893 
894  QSqlTableModel effectivefov(nullptr, db);
895  effectivefov.setTable("effectivefov");
896  effectivefov.select();
897 
898  for (int i = 0; i < effectivefov.rowCount(); ++i)
899  {
900  QVariantMap recordMap;
901  QSqlRecord record = effectivefov.record(i);
902  for (int j = 0; j < record.count(); j++)
903  recordMap[record.fieldName(j)] = record.value(j);
904 
905  effectiveFOVs.append(recordMap);
906  }
907 
908  return true;
909 }
910 
911 /* Optical Trains Section */
912 
913 ////////////////////////////////////////////////////////////////////////////////////////////////////////
914 ///
915 ////////////////////////////////////////////////////////////////////////////////////////////////////////
916 bool KSUserDB::AddOpticalTrain(const QVariantMap &oneTrain)
917 {
918  auto db = QSqlDatabase::database(m_ConnectionName);
919  if (!db.isValid())
920  {
921  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
922  return false;
923  }
924 
925  QSqlTableModel opticalTrain(nullptr, db);
926  opticalTrain.setTable("opticaltrains");
927  opticalTrain.select();
928 
929  QSqlRecord record = opticalTrain.record();
930 
931  // Remove PK so that it gets auto-incremented later
932  record.remove(0);
933 
934  for (QVariantMap::const_iterator iter = oneTrain.begin(); iter != oneTrain.end(); ++iter)
935  record.setValue(iter.key(), iter.value());
936 
937  opticalTrain.insertRecord(-1, record);
938 
939  if (!opticalTrain.submitAll())
940  {
941  qCWarning(KSTARS) << opticalTrain.lastError();
942  return false;
943  }
944 
945  return true;
946 }
947 
948 ////////////////////////////////////////////////////////////////////////////////////////////////////////
949 ///
950 ////////////////////////////////////////////////////////////////////////////////////////////////////////
951 bool KSUserDB::UpdateOpticalTrain(const QVariantMap &oneTrain, int id)
952 {
953  auto db = QSqlDatabase::database(m_ConnectionName);
954  if (!db.isValid())
955  {
956  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
957  return false;
958  }
959 
960  QSqlTableModel opticalTrain(nullptr, db);
961  opticalTrain.setTable("opticaltrains");
962  opticalTrain.setFilter(QString("id=%1").arg(id));
963  opticalTrain.select();
964 
965  QSqlRecord record = opticalTrain.record(0);
966 
967  for (QVariantMap::const_iterator iter = oneTrain.begin(); iter != oneTrain.end(); ++iter)
968  record.setValue(iter.key(), iter.value());
969 
970  opticalTrain.setRecord(0, record);
971 
972  if (!opticalTrain.submitAll())
973  {
974  qCWarning(KSTARS) << opticalTrain.lastError();
975  return false;
976  }
977 
978  return true;
979 }
980 
981 ////////////////////////////////////////////////////////////////////////////////////////////////////////
982 ///
983 ////////////////////////////////////////////////////////////////////////////////////////////////////////
984 bool KSUserDB::DeleteOpticalTrain(int id)
985 {
986  auto db = QSqlDatabase::database(m_ConnectionName);
987  if (!db.isValid())
988  {
989  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
990  return false;
991  }
992 
993  QSqlTableModel opticalTrain(nullptr, db);
994  opticalTrain.setTable("opticaltrains");
995  opticalTrain.setFilter(QString("id=%1").arg(id));
996 
997  opticalTrain.select();
998 
999  opticalTrain.removeRows(0, 1);
1000  opticalTrain.submitAll();
1001  return true;
1002 }
1003 
1004 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1005 ///
1006 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1007 bool KSUserDB::GetOpticalTrains(uint32_t profileID, QList<QVariantMap> &opticalTrains)
1008 {
1009  auto db = QSqlDatabase::database(m_ConnectionName);
1010  if (!db.isValid())
1011  {
1012  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1013  return false;
1014  }
1015 
1016  opticalTrains.clear();
1017 
1018  QSqlTableModel opticalTrain(nullptr, db);
1019  opticalTrain.setTable("opticaltrains");
1020  opticalTrain.setFilter(QString("profile=%1").arg(profileID));
1021  opticalTrain.select();
1022 
1023  for (int i = 0; i < opticalTrain.rowCount(); ++i)
1024  {
1025  QVariantMap recordMap;
1026  QSqlRecord record = opticalTrain.record(i);
1027  for (int j = 0; j < record.count(); j++)
1028  recordMap[record.fieldName(j)] = record.value(j);
1029 
1030  opticalTrains.append(recordMap);
1031  }
1032 
1033  return true;
1034 }
1035 
1036 /* Driver Alias Section */
1037 
1038 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1039 ///
1040 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1041 bool KSUserDB::AddCustomDriver(const QVariantMap &oneDriver)
1042 {
1043  auto db = QSqlDatabase::database(m_ConnectionName);
1044  if (!db.isValid())
1045  {
1046  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1047  return false;
1048  }
1049 
1050  QSqlTableModel CustomDriver(nullptr, db);
1051  CustomDriver.setTable("customdrivers");
1052  CustomDriver.select();
1053 
1054  QSqlRecord record = CustomDriver.record();
1055 
1056  // Remove PK so that it gets auto-incremented later
1057  record.remove(0);
1058 
1059  for (QVariantMap::const_iterator iter = oneDriver.begin(); iter != oneDriver.end(); ++iter)
1060  record.setValue(iter.key(), iter.value());
1061 
1062  bool rc = CustomDriver.insertRecord(-1, record);
1063  if (rc == false)
1064  return rc;
1065 
1066  rc = CustomDriver.submitAll();
1067 
1068  return rc;
1069 }
1070 
1071 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1072 ///
1073 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1074 bool KSUserDB::DeleteCustomDriver(const QString &id)
1075 {
1076  auto db = QSqlDatabase::database(m_ConnectionName);
1077  if (!db.isValid())
1078  {
1079  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1080  return false;
1081  }
1082 
1083  QSqlTableModel CustomDriver(nullptr, db);
1084  CustomDriver.setTable("customdrivers");
1085  CustomDriver.setFilter("id = \'" + id + "\'");
1086 
1087  CustomDriver.select();
1088 
1089  CustomDriver.removeRows(0, 1);
1090  CustomDriver.submitAll();
1091 
1092  return true;
1093 }
1094 
1095 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1096 ///
1097 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1098 bool KSUserDB::GetAllCustomDrivers(QList<QVariantMap> &CustomDrivers)
1099 {
1100  auto db = QSqlDatabase::database(m_ConnectionName);
1101  if (!db.isValid())
1102  {
1103  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1104  return false;
1105  }
1106 
1107  CustomDrivers.clear();
1108  QSqlTableModel CustomDriver(nullptr, db);
1109  CustomDriver.setTable("customdrivers");
1110  CustomDriver.select();
1111 
1112  for (int i = 0; i < CustomDriver.rowCount(); ++i)
1113  {
1114  QVariantMap recordMap;
1115  QSqlRecord record = CustomDriver.record(i);
1116  for (int j = 0; j < record.count(); j++)
1117  recordMap[record.fieldName(j)] = record.value(j);
1118 
1119  CustomDrivers.append(recordMap);
1120  }
1121 
1122  return true;
1123 }
1124 
1125 /* HiPS Section */
1126 
1127 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1128 ///
1129 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1130 bool KSUserDB::AddHIPSSource(const QMap<QString, QString> &oneSource)
1131 {
1132  auto db = QSqlDatabase::database(m_ConnectionName);
1133  if (!db.isValid())
1134  {
1135  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1136  return false;
1137  }
1138 
1139  QSqlTableModel HIPSSource(nullptr, db);
1140  HIPSSource.setTable("hips");
1141  HIPSSource.select();
1142 
1143  QSqlRecord record = HIPSSource.record();
1144 
1145  for (QMap<QString, QString>::const_iterator iter = oneSource.begin(); iter != oneSource.end(); ++iter)
1146  record.setValue(iter.key(), iter.value());
1147 
1148  HIPSSource.insertRecord(-1, record);
1149  HIPSSource.submitAll();
1150 
1151  return true;
1152 }
1153 
1154 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1155 ///
1156 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1157 bool KSUserDB::DeleteHIPSSource(const QString &ID)
1158 {
1159  auto db = QSqlDatabase::database(m_ConnectionName);
1160  if (!db.isValid())
1161  {
1162  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1163  return false;
1164  }
1165 
1166  QSqlTableModel HIPSSource(nullptr, db);
1167  HIPSSource.setTable("hips");
1168  HIPSSource.setFilter("ID = \'" + ID + "\'");
1169 
1170  HIPSSource.select();
1171 
1172  HIPSSource.removeRows(0, 1);
1173  HIPSSource.submitAll();
1174 
1175  return true;
1176 }
1177 
1178 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1179 ///
1180 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1181 bool KSUserDB::GetAllHIPSSources(QList<QMap<QString, QString>> &HIPSSources)
1182 {
1183  auto db = QSqlDatabase::database(m_ConnectionName);
1184  if (!db.isValid())
1185  {
1186  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1187  return false;
1188  }
1189 
1190  HIPSSources.clear();
1191  QSqlTableModel HIPSSource(nullptr, db);
1192  HIPSSource.setTable("hips");
1193  HIPSSource.select();
1194 
1195  for (int i = 0; i < HIPSSource.rowCount(); ++i)
1196  {
1197  QMap<QString, QString> recordMap;
1198  QSqlRecord record = HIPSSource.record(i);
1199  for (int j = 1; j < record.count(); j++)
1200  recordMap[record.fieldName(j)] = record.value(j).toString();
1201 
1202  HIPSSources.append(recordMap);
1203  }
1204 
1205  return true;
1206 }
1207 
1208 
1209 /* DSLR Section */
1210 
1211 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1212 ///
1213 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1214 bool KSUserDB::AddDSLRInfo(const QMap<QString, QVariant> &oneInfo)
1215 {
1216  auto db = QSqlDatabase::database(m_ConnectionName);
1217  if (!db.isValid())
1218  {
1219  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1220  return false;
1221  }
1222 
1223  QSqlTableModel DSLRInfo(nullptr, db);
1224  DSLRInfo.setTable("dslr");
1225  DSLRInfo.select();
1226 
1227  QSqlRecord record = DSLRInfo.record();
1228 
1229  for (QMap<QString, QVariant>::const_iterator iter = oneInfo.begin(); iter != oneInfo.end(); ++iter)
1230  record.setValue(iter.key(), iter.value());
1231 
1232  DSLRInfo.insertRecord(-1, record);
1233  DSLRInfo.submitAll();
1234 
1235  return true;
1236 }
1237 
1238 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1239 ///
1240 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1241 bool KSUserDB::DeleteAllDSLRInfo()
1242 {
1243  auto db = QSqlDatabase::database(m_ConnectionName);
1244  if (!db.isValid())
1245  {
1246  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1247  return false;
1248  }
1249 
1250  QSqlTableModel DSLRInfo(nullptr, db);
1251  DSLRInfo.setTable("dslr");
1252  DSLRInfo.select();
1253 
1254  DSLRInfo.removeRows(0, DSLRInfo.rowCount());
1255  DSLRInfo.submitAll();
1256 
1257  return true;
1258 }
1259 
1260 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1261 ///
1262 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1263 bool KSUserDB::DeleteDSLRInfo(const QString &model)
1264 {
1265  auto db = QSqlDatabase::database(m_ConnectionName);
1266  if (!db.isValid())
1267  {
1268  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1269  return false;
1270  }
1271 
1272  QSqlTableModel DSLRInfo(nullptr, db);
1273  DSLRInfo.setTable("dslr");
1274  DSLRInfo.setFilter("model = \'" + model + "\'");
1275 
1276  DSLRInfo.select();
1277 
1278  DSLRInfo.removeRows(0, 1);
1279  DSLRInfo.submitAll();
1280 
1281  return true;
1282 }
1283 
1284 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1285 ///
1286 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1287 bool KSUserDB::GetAllDSLRInfos(QList<QMap<QString, QVariant>> &DSLRInfos)
1288 {
1289  auto db = QSqlDatabase::database(m_ConnectionName);
1290  if (!db.isValid())
1291  {
1292  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1293  return false;
1294  }
1295 
1296  DSLRInfos.clear();
1297 
1298  QSqlTableModel DSLRInfo(nullptr, db);
1299  DSLRInfo.setTable("dslr");
1300  DSLRInfo.select();
1301 
1302  for (int i = 0; i < DSLRInfo.rowCount(); ++i)
1303  {
1304  QMap<QString, QVariant> recordMap;
1305  QSqlRecord record = DSLRInfo.record(i);
1306  for (int j = 1; j < record.count(); j++)
1307  recordMap[record.fieldName(j)] = record.value(j);
1308 
1309  DSLRInfos.append(recordMap);
1310  }
1311 
1312  return true;
1313 }
1314 
1315 /*
1316  * Flag Section
1317 */
1318 
1319 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1320 ///
1321 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1323 {
1324  auto db = QSqlDatabase::database(m_ConnectionName);
1325  if (!db.isValid())
1326  {
1327  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1328  return false;
1329  }
1330 
1331  QSqlTableModel flags(nullptr, db);
1333  flags.setTable("flags");
1334  flags.select();
1335 
1336  flags.removeRows(0, flags.rowCount());
1337  flags.submitAll();
1338 
1339  flags.clear();
1340 
1341  return true;
1342 }
1343 
1344 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1345 ///
1346 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1347 bool KSUserDB::AddFlag(const QString &ra, const QString &dec, const QString &epoch, const QString &image_name,
1348  const QString &label, const QString &labelColor)
1349 {
1350  auto db = QSqlDatabase::database(m_ConnectionName);
1351  if (!db.isValid())
1352  {
1353  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1354  return false;
1355  }
1356 
1357  QSqlTableModel flags(nullptr, db);
1358  flags.setTable("flags");
1359 
1360  int row = 0;
1361  flags.insertRows(row, 1);
1362  flags.setData(flags.index(row, 1), ra); // row,0 is autoincerement ID
1363  flags.setData(flags.index(row, 2), dec);
1364  flags.setData(flags.index(row, 3), image_name);
1365  flags.setData(flags.index(row, 4), label);
1366  flags.setData(flags.index(row, 5), labelColor);
1367  flags.setData(flags.index(row, 6), epoch);
1368  flags.submitAll();
1369 
1370  flags.clear();
1371  return true;
1372 }
1373 
1374 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1375 ///
1376 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1378 {
1379  auto db = QSqlDatabase::database(m_ConnectionName);
1380  if (!db.isValid())
1381  {
1382  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1383  return false;
1384  }
1385 
1386  QSqlTableModel flags(nullptr, db);
1387  flags.setTable("flags");
1388  flags.select();
1389 
1390  for (int i = 0; i < flags.rowCount(); ++i)
1391  {
1392  QStringList flagEntry;
1393  QSqlRecord record = flags.record(i);
1394  /* flagEntry order description
1395  * The variation in the order is due to variation
1396  * in flag entry description order and flag database
1397  * description order.
1398  * flag (database): ra, dec, icon, label, color, epoch
1399  * flag (object): ra, dec, epoch, icon, label, color
1400  */
1401  flagEntry.append(record.value(1).toString());
1402  flagEntry.append(record.value(2).toString());
1403  flagEntry.append(record.value(6).toString());
1404  flagEntry.append(record.value(3).toString());
1405  flagEntry.append(record.value(4).toString());
1406  flagEntry.append(record.value(5).toString());
1407  flagList.append(flagEntry);
1408  }
1409 
1410  flags.clear();
1411  return true;
1412 }
1413 
1414 /*
1415  * Generic Section
1416  */
1417 
1418 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1419 ///
1420 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1421 bool KSUserDB::DeleteEquipment(const QString &type, const QString &id)
1422 {
1423  auto db = QSqlDatabase::database(m_ConnectionName);
1424  if (!db.isValid())
1425  {
1426  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1427  return false;
1428  }
1429 
1430  QSqlTableModel equip(nullptr, db);
1431  equip.setTable(type);
1432  equip.setFilter("id = " + id);
1433  equip.select();
1434 
1435  equip.removeRows(0, equip.rowCount());
1436  equip.submitAll();
1437  equip.clear();
1438 
1439  return true;
1440 }
1441 
1442 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1443 ///
1444 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1446 {
1447  auto db = QSqlDatabase::database(m_ConnectionName);
1448  if (!db.isValid())
1449  {
1450  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1451  return false;
1452  }
1453 
1454  QSqlTableModel equip(nullptr, db);
1456  equip.setTable(type);
1457  equip.setFilter("id >= 1");
1458  equip.select();
1459  equip.removeRows(0, equip.rowCount());
1460  equip.submitAll();
1461  equip.clear();
1462 
1463  return true;
1464 }
1465 
1466 /*
1467  * Telescope section
1468  */
1469 
1470 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1471 ///
1472 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1473 bool KSUserDB::AddScope(const QString &model, const QString &vendor, const QString &type, const double &aperture,
1474  const double &focalLength)
1475 {
1476  auto db = QSqlDatabase::database(m_ConnectionName);
1477  if (!db.isValid())
1478  {
1479  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1480  return false;
1481  }
1482 
1483  QSqlTableModel equip(nullptr, db);
1484  equip.setTable("telescope");
1485 
1486  QSqlRecord record = equip.record();
1487  record.setValue("Vendor", vendor);
1488  record.setValue("Aperture", aperture);
1489  record.setValue("Model", model);
1490  record.setValue("Type", type);
1491  record.setValue("FocalLength", focalLength);
1492 
1493  equip.insertRecord(-1, record);
1494 
1495  if (!equip.submitAll())
1496  qCWarning(KSTARS) << equip.lastError().text();
1497 
1498  equip.clear();
1499 
1500  return true;
1501 }
1502 
1503 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1504 ///
1505 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1506 bool KSUserDB::AddScope(const QString &model, const QString &vendor, const QString &type,
1507  const double &aperture, const double &focalLength, const QString &id)
1508 {
1509  auto db = QSqlDatabase::database(m_ConnectionName);
1510  if (!db.isValid())
1511  {
1512  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1513  return false;
1514  }
1515 
1516  QSqlTableModel equip(nullptr, db);
1517  equip.setTable("telescope");
1518  equip.setFilter("id = " + id);
1519  equip.select();
1520 
1521  if (equip.rowCount() > 0)
1522  {
1523  QSqlRecord record = equip.record(0);
1524  record.setValue("Vendor", vendor);
1525  record.setValue("Aperture", aperture);
1526  record.setValue("Model", model);
1527  record.setValue("Type", type);
1528  record.setValue("FocalLength", focalLength);
1529  equip.setRecord(0, record);
1530  equip.submitAll();
1531  }
1532 
1533  return true;
1534 }
1535 
1536 #ifndef KSTARS_LITE
1537 
1538 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1539 ///
1540 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1542 {
1543  auto db = QSqlDatabase::database(m_ConnectionName);
1544  if (!db.isValid())
1545  {
1546  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1547  return false;
1548  }
1549 
1550  qDeleteAll(scope_list);
1551  scope_list.clear();
1552 
1553  QSqlTableModel equip(nullptr, db);
1554  equip.setTable("telescope");
1555  equip.select();
1556 
1557  for (int i = 0; i < equip.rowCount(); ++i)
1558  {
1559  QSqlRecord record = equip.record(i);
1560  QString id = record.value("id").toString();
1561  QString vendor = record.value("Vendor").toString();
1562  double aperture = record.value("Aperture").toDouble();
1563  QString model = record.value("Model").toString();
1564  QString type = record.value("Type").toString();
1565  double focalLength = record.value("FocalLength").toDouble();
1566  OAL::Scope *o = new OAL::Scope(id, model, vendor, type, focalLength, aperture);
1567  scope_list.append(o);
1568  }
1569 
1570  equip.clear();
1571  return true;
1572 }
1573 #endif
1574 /*
1575  * Eyepiece section
1576  */
1577 
1578 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1579 ///
1580 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1581 bool KSUserDB::AddEyepiece(const QString &vendor, const QString &model, const double &focalLength, const double &fov,
1582  const QString &fovunit)
1583 {
1584  auto db = QSqlDatabase::database(m_ConnectionName);
1585  if (!db.isValid())
1586  {
1587  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1588  return false;
1589  }
1590 
1591  QSqlTableModel equip(nullptr, db);
1592  equip.setTable("eyepiece");
1593 
1594  int row = 0;
1595  equip.insertRows(row, 1);
1596  equip.setData(equip.index(row, 1), vendor); // row,0 is autoincerement ID
1597  equip.setData(equip.index(row, 2), model);
1598  equip.setData(equip.index(row, 3), focalLength);
1599  equip.setData(equip.index(row, 4), fov);
1600  equip.setData(equip.index(row, 5), fovunit);
1601  equip.submitAll();
1602  equip.clear();
1603 
1604  return true;
1605 }
1606 
1607 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1608 ///
1609 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1610 bool KSUserDB::AddEyepiece(const QString &vendor, const QString &model, const double &focalLength, const double &fov,
1611  const QString &fovunit, const QString &id)
1612 {
1613  auto db = QSqlDatabase::database(m_ConnectionName);
1614  if (!db.isValid())
1615  {
1616  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1617  return false;
1618  }
1619 
1620  QSqlTableModel equip(nullptr, db);
1621  equip.setTable("eyepiece");
1622  equip.setFilter("id = " + id);
1623  equip.select();
1624 
1625  if (equip.rowCount() > 0)
1626  {
1627  QSqlRecord record = equip.record(0);
1628  record.setValue(1, vendor);
1629  record.setValue(2, model);
1630  record.setValue(3, focalLength);
1631  record.setValue(4, fov);
1632  record.setValue(5, fovunit);
1633  equip.setRecord(0, record);
1634  equip.submitAll();
1635  }
1636 
1637  return true;
1638 }
1639 
1640 #ifndef KSTARS_LITE
1641 
1642 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1643 ///
1644 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1646 {
1647  auto db = QSqlDatabase::database(m_ConnectionName);
1648  if (!db.isValid())
1649  {
1650  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1651  return false;
1652  }
1653 
1654  eyepiece_list.clear();
1655 
1656  QSqlTableModel equip(nullptr, db);
1657  equip.setTable("eyepiece");
1658  equip.select();
1659 
1660  for (int i = 0; i < equip.rowCount(); ++i)
1661  {
1662  QSqlRecord record = equip.record(i);
1663  QString id = record.value("id").toString();
1664  QString vendor = record.value("Vendor").toString();
1665  QString model = record.value("Model").toString();
1666  double focalLength = record.value("FocalLength").toDouble();
1667  double fov = record.value("ApparentFOV").toDouble();
1668  QString fovUnit = record.value("FOVUnit").toString();
1669 
1670  OAL::Eyepiece *o = new OAL::Eyepiece(id, model, vendor, fov, fovUnit, focalLength);
1671  eyepiece_list.append(o);
1672  }
1673 
1674  equip.clear();
1675  return true;
1676 }
1677 #endif
1678 /*
1679  * lens section
1680  */
1681 
1682 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1683 ///
1684 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1685 bool KSUserDB::AddLens(const QString &vendor, const QString &model, const double &factor)
1686 {
1687  auto db = QSqlDatabase::database(m_ConnectionName);
1688  if (!db.isValid())
1689  {
1690  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1691  return false;
1692  }
1693 
1694  QSqlTableModel equip(nullptr, db);
1695  equip.setTable("lens");
1696 
1697  int row = 0;
1698  equip.insertRows(row, 1);
1699  equip.setData(equip.index(row, 1), vendor); // row,0 is autoincerement ID
1700  equip.setData(equip.index(row, 2), model);
1701  equip.setData(equip.index(row, 3), factor);
1702  equip.submitAll();
1703 
1704  equip.clear();
1705  return true;
1706 }
1707 
1708 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1709 ///
1710 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1711 bool KSUserDB::AddLens(const QString &vendor, const QString &model, const double &factor, const QString &id)
1712 {
1713  auto db = QSqlDatabase::database(m_ConnectionName);
1714  if (!db.isValid())
1715  {
1716  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1717  return false;
1718  }
1719 
1720  QSqlTableModel equip(nullptr, db);
1721  equip.setTable("lens");
1722  equip.setFilter("id = " + id);
1723  equip.select();
1724 
1725  if (equip.rowCount() > 0)
1726  {
1727  QSqlRecord record = equip.record(0);
1728  record.setValue(1, vendor);
1729  record.setValue(2, model);
1730  record.setValue(3, factor);
1731  equip.submitAll();
1732  }
1733 
1734  return true;
1735 }
1736 #ifndef KSTARS_LITE
1737 
1738 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1739 ///
1740 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1742 {
1743  auto db = QSqlDatabase::database(m_ConnectionName);
1744  if (!db.isValid())
1745  {
1746  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1747  return false;
1748  }
1749 
1750  qDeleteAll(lens_list);
1751  lens_list.clear();
1752 
1753  QSqlTableModel equip(nullptr, db);
1754  equip.setTable("lens");
1755  equip.select();
1756 
1757  for (int i = 0; i < equip.rowCount(); ++i)
1758  {
1759  QSqlRecord record = equip.record(i);
1760  QString id = record.value("id").toString();
1761  QString vendor = record.value("Vendor").toString();
1762  QString model = record.value("Model").toString();
1763  double factor = record.value("Factor").toDouble();
1764  OAL::Lens *o = new OAL::Lens(id, model, vendor, factor);
1765  lens_list.append(o);
1766  }
1767 
1768  equip.clear();
1769  return true;
1770 }
1771 #endif
1772 /*
1773  * filter section
1774  */
1775 
1776 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1777 ///
1778 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1779 bool KSUserDB::AddFilter(const filterProperties *fp)
1780 {
1781  auto db = QSqlDatabase::database(m_ConnectionName);
1782  if (!db.isValid())
1783  {
1784  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1785  return false;
1786  }
1787 
1788  QSqlTableModel equip(nullptr, db);
1789  equip.setTable("filter");
1790 
1791  QSqlRecord record = equip.record();
1792  record.setValue("Vendor", fp->vendor);
1793  record.setValue("Model", fp->model);
1794  record.setValue("Type", fp->type);
1795  record.setValue("Color", fp->color);
1796  record.setValue("Offset", fp->offset);
1797  record.setValue("Exposure", fp->exposure);
1798  record.setValue("UseAutoFocus", fp->useAutoFocus ? 1 : 0);
1799  record.setValue("LockedFilter", fp->lockedFilter);
1800  record.setValue("AbsoluteFocusPosition", fp->absFocusPos);
1801  record.setValue("FocusTemperature", fp->focusTemperature);
1802  record.setValue("FocusAltitude", fp->focusAltitude);
1803  record.setValue("FocusTicksPerTemp", fp->focusTicksPerTemp);
1804  record.setValue("FocusTicksPerAlt", fp->focusTicksPerAlt);
1805  record.setValue("Wavelength", fp->wavelength);
1806 
1807  if (equip.insertRecord(-1, record) == false)
1808  qCritical() << __FUNCTION__ << equip.lastError();
1809 
1810  if (equip.submitAll() == false)
1811  qCritical() << "AddFilter:" << equip.lastError();
1812 
1813  equip.clear();
1814  return true;
1815 }
1816 
1817 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1818 ///
1819 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1820 bool KSUserDB::AddFilter(const filterProperties *fp, const QString &id)
1821 {
1822  auto db = QSqlDatabase::database(m_ConnectionName);
1823  if (!db.isValid())
1824  {
1825  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1826  return false;
1827  }
1828 
1829  QSqlTableModel equip(nullptr, db);
1830  equip.setTable("filter");
1831  equip.setFilter("id = " + id);
1832  equip.select();
1833 
1834  if (equip.rowCount() > 0)
1835  {
1836  QSqlRecord record = equip.record(0);
1837  record.setValue("Vendor", fp->vendor);
1838  record.setValue("Model", fp->model);
1839  record.setValue("Type", fp->type);
1840  record.setValue("Color", fp->color);
1841  record.setValue("Offset", fp->offset);
1842  record.setValue("Exposure", fp->exposure);
1843  record.setValue("UseAutoFocus", fp->useAutoFocus ? 1 : 0);
1844  record.setValue("LockedFilter", fp->lockedFilter);
1845  record.setValue("AbsoluteFocusPosition", fp->absFocusPos);
1846  record.setValue("FocusTemperature", fp->focusTemperature);
1847  record.setValue("FocusAltitude", fp->focusAltitude);
1848  record.setValue("FocusTicksPerTemp", fp->focusTicksPerTemp);
1849  record.setValue("FocusTicksPerAlt", fp->focusTicksPerAlt);
1850  record.setValue("Wavelength", fp->wavelength);
1851  equip.setRecord(0, record);
1852  if (equip.submitAll() == false)
1853  qCritical() << "AddFilter:" << equip.lastError();
1854  }
1855 
1856  return true;
1857 }
1858 
1859 #ifndef KSTARS_LITE
1860 
1861 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1862 ///
1863 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1865 {
1866  auto db = QSqlDatabase::database(m_ConnectionName);
1867  if (!db.isValid())
1868  {
1869  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
1870  return false;
1871  }
1872 
1873  filter_list.clear();
1874  QSqlTableModel equip(nullptr, db);
1875  equip.setTable("filter");
1876  equip.select();
1877 
1878  filterProperties *fp = new filterProperties("", "", "", "");
1879 
1880  for (int i = 0; i < equip.rowCount(); ++i)
1881  {
1882  QSqlRecord record = equip.record(i);
1883  QString id = record.value("id").toString();
1884  fp->vendor = record.value("Vendor").toString();
1885  fp->model = record.value("Model").toString();
1886  fp->type = record.value("Type").toString();
1887  fp->color = record.value("Color").toString();
1888  fp->offset = record.value("Offset").toInt();
1889  fp->exposure = record.value("Exposure").toDouble();
1890  fp->lockedFilter = record.value("LockedFilter").toString();
1891  fp->useAutoFocus = record.value("UseAutoFocus").toInt() == 1;
1892  fp->absFocusPos = record.value("AbsoluteFocusPosition").toInt();
1893  fp->focusTemperature = record.value("FocusTemperature").toDouble();
1894  fp->focusAltitude = record.value("FocusAltitude").toDouble();
1895  fp->focusTicksPerTemp = record.value("FocusTicksPerTemp").toDouble();
1896  fp->focusTicksPerAlt = record.value("FocusTicksPerAlt").toDouble();
1897  fp->wavelength = record.value("Wavelength").toDouble();
1898  OAL::Filter *o = new OAL::Filter(id, fp);
1899  filter_list.append(o);
1900  }
1901 
1902  equip.clear();
1903  return true;
1904 }
1905 #endif
1906 
1907 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1908 ///
1909 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1910 void KSUserDB::readScopes()
1911 {
1912  while (!reader_->atEnd())
1913  {
1914  reader_->readNext();
1915 
1916  if (reader_->isEndElement())
1917  break;
1918 
1919  if (reader_->isStartElement())
1920  {
1921  if (reader_->name() == "scope")
1922  readScope();
1923  }
1924  }
1925 }
1926 
1927 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1928 ///
1929 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1930 void KSUserDB::readEyepieces()
1931 {
1932  while (!reader_->atEnd())
1933  {
1934  reader_->readNext();
1935 
1936  if (reader_->isEndElement())
1937  break;
1938 
1939  if (reader_->isStartElement())
1940  {
1941  if (reader_->name() == "eyepiece")
1942  readEyepiece();
1943  }
1944  }
1945 }
1946 
1947 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1948 ///
1949 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1950 void KSUserDB::readLenses()
1951 {
1952  while (!reader_->atEnd())
1953  {
1954  reader_->readNext();
1955 
1956  if (reader_->isEndElement())
1957  break;
1958 
1959  if (reader_->isStartElement())
1960  {
1961  if (reader_->name() == "lens")
1962  readLens();
1963  }
1964  }
1965 }
1966 
1967 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1968 ///
1969 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1970 void KSUserDB::readFilters()
1971 {
1972  while (!reader_->atEnd())
1973  {
1974  reader_->readNext();
1975 
1976  if (reader_->isEndElement())
1977  break;
1978 
1979  if (reader_->isStartElement())
1980  {
1981  if (reader_->name() == "filter")
1982  readFilter();
1983  }
1984  }
1985 }
1986 
1987 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1988 ///
1989 ////////////////////////////////////////////////////////////////////////////////////////////////////////
1990 void KSUserDB::readScope()
1991 {
1992  QString model, vendor, type;
1993  double aperture = 0, focalLength = 0;
1994 
1995  while (!reader_->atEnd())
1996  {
1997  reader_->readNext();
1998 
1999  if (reader_->isEndElement())
2000  break;
2001 
2002  if (reader_->isStartElement())
2003  {
2004  if (reader_->name() == "model")
2005  {
2006  model = reader_->readElementText();
2007  }
2008  else if (reader_->name() == "vendor")
2009  {
2010  vendor = reader_->readElementText();
2011  }
2012  else if (reader_->name() == "type")
2013  {
2014  type = reader_->readElementText();
2015  if (type == "N")
2016  type = "Newtonian";
2017  if (type == "R")
2018  type = "Refractor";
2019  if (type == "M")
2020  type = "Maksutov";
2021  if (type == "S")
2022  type = "Schmidt-Cassegrain";
2023  if (type == "K")
2024  type = "Kutter (Schiefspiegler)";
2025  if (type == "C")
2026  type = "Cassegrain";
2027  if (type == "RC")
2028  type = "Ritchey-Chretien";
2029  }
2030  else if (reader_->name() == "focalLength")
2031  {
2032  focalLength = (reader_->readElementText()).toDouble();
2033  }
2034  else if (reader_->name() == "aperture")
2035  aperture = (reader_->readElementText()).toDouble();
2036  }
2037  }
2038 
2039  AddScope(model, vendor, type, focalLength, aperture);
2040 }
2041 
2042 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2043 ///
2044 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2045 void KSUserDB::readEyepiece()
2046 {
2047  QString model, focalLength, vendor, fov, fovUnit;
2048  while (!reader_->atEnd())
2049  {
2050  reader_->readNext();
2051 
2052  if (reader_->isEndElement())
2053  break;
2054 
2055  if (reader_->isStartElement())
2056  {
2057  if (reader_->name() == "model")
2058  {
2059  model = reader_->readElementText();
2060  }
2061  else if (reader_->name() == "vendor")
2062  {
2063  vendor = reader_->readElementText();
2064  }
2065  else if (reader_->name() == "apparentFOV")
2066  {
2067  fov = reader_->readElementText();
2068  fovUnit = reader_->attributes().value("unit").toString();
2069  }
2070  else if (reader_->name() == "focalLength")
2071  {
2072  focalLength = reader_->readElementText();
2073  }
2074  }
2075  }
2076 
2077  AddEyepiece(vendor, model, focalLength.toDouble(), fov.toDouble(), fovUnit);
2078 }
2079 
2080 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2081 ///
2082 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2083 void KSUserDB::readLens()
2084 {
2085  QString model, factor, vendor;
2086  while (!reader_->atEnd())
2087  {
2088  reader_->readNext();
2089 
2090  if (reader_->isEndElement())
2091  break;
2092 
2093  if (reader_->isStartElement())
2094  {
2095  if (reader_->name() == "model")
2096  {
2097  model = reader_->readElementText();
2098  }
2099  else if (reader_->name() == "vendor")
2100  {
2101  vendor = reader_->readElementText();
2102  }
2103  else if (reader_->name() == "factor")
2104  {
2105  factor = reader_->readElementText();
2106  }
2107  }
2108  }
2109 
2110  AddLens(vendor, model, factor.toDouble());
2111 }
2112 
2113 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2114 ///
2115 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2116 void KSUserDB::readFilter()
2117 {
2118  filterProperties *fp = new filterProperties("", "", "", "");
2119 
2120  while (!reader_->atEnd())
2121  {
2122  reader_->readNext();
2123 
2124  if (reader_->isEndElement())
2125  break;
2126 
2127  if (reader_->isStartElement())
2128  {
2129  if (reader_->name() == "model")
2130  {
2131  fp->model = reader_->readElementText();
2132  }
2133  else if (reader_->name() == "vendor")
2134  {
2135  fp->vendor = reader_->readElementText();
2136  }
2137  else if (reader_->name() == "type")
2138  {
2139  fp->type = reader_->readElementText();
2140  }
2141  else if (reader_->name() == "offset")
2142  {
2143  fp->offset = reader_->readElementText().toInt();
2144  }
2145  else if (reader_->name() == "color")
2146  {
2147  fp->color = reader_->readElementText();
2148  }
2149  else if (reader_->name() == "exposure")
2150  {
2151  fp->exposure = reader_->readElementText().toDouble();
2152  }
2153  else if (reader_->name() == "lockedFilter")
2154  {
2155  fp->lockedFilter = reader_->readElementText();
2156  }
2157  else if (reader_->name() == "useAutoFocus")
2158  {
2159  fp->useAutoFocus = (reader_->readElementText() == "1");
2160  }
2161  else if (reader_->name() == "AbsoluteAutoFocus")
2162  {
2163  fp->absFocusPos = (reader_->readElementText().toInt());
2164  }
2165  else if (reader_->name() == "FocusTemperature")
2166  {
2167  fp->focusTemperature = (reader_->readElementText().toDouble());
2168  }
2169  else if (reader_->name() == "FocusAltitude")
2170  {
2171  fp->focusAltitude = (reader_->readElementText().toDouble());
2172  }
2173  else if (reader_->name() == "FocusTicksPerTemp")
2174  {
2175  fp->focusTicksPerTemp = (reader_->readElementText().toDouble());
2176  }
2177  else if (reader_->name() == "FocusTicksPerAlt")
2178  {
2179  fp->focusTicksPerAlt = (reader_->readElementText().toDouble());
2180  }
2181  else if (reader_->name() == "Wavelength")
2182  {
2183  fp->wavelength = (reader_->readElementText().toDouble());
2184  }
2185  }
2186  }
2187  AddFilter(fp);
2188 }
2189 
2191 {
2192  auto db = QSqlDatabase::database(m_ConnectionName);
2193  if (!db.isValid())
2194  {
2195  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2196  return false;
2197  }
2198 
2199  qDeleteAll(horizonList);
2200  horizonList.clear();
2201  QSqlTableModel regions(nullptr, db);
2202  regions.setTable("horizons");
2203  regions.select();
2204 
2205  QSqlTableModel points(nullptr, db);
2206 
2207  for (int i = 0; i < regions.rowCount(); ++i)
2208  {
2209  QSqlRecord record = regions.record(i);
2210  const QString regionTable = record.value("name").toString();
2211  const QString regionName = record.value("label").toString();
2212 
2213  const int flags = record.value("enabled").toInt();
2214  const bool enabled = flags & 0x1 ? true : false;
2215  const bool ceiling = flags & 0x2 ? true : false;
2216 
2217  points.setTable(regionTable);
2218  points.select();
2219 
2220  std::shared_ptr<LineList> skyList(new LineList());
2221 
2222  ArtificialHorizonEntity *horizon = new ArtificialHorizonEntity;
2223 
2224  horizon->setRegion(regionName);
2225  horizon->setEnabled(enabled);
2226  horizon->setCeiling(ceiling);
2227  horizon->setList(skyList);
2228 
2229  horizonList.append(horizon);
2230 
2231  for (int j = 0; j < points.rowCount(); j++)
2232  {
2233  std::shared_ptr<SkyPoint> p(new SkyPoint());
2234 
2235  record = points.record(j);
2236  p->setAz(record.value(0).toDouble());
2237  p->setAlt(record.value(1).toDouble());
2238  p->HorizontalToEquatorial(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
2239  skyList->append(std::move(p));
2240  }
2241 
2242  points.clear();
2243  }
2244 
2245  regions.clear();
2246 
2247  return true;
2248 }
2249 
2251 {
2252  auto db = QSqlDatabase::database(m_ConnectionName);
2253  if (!db.isValid())
2254  {
2255  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2256  return false;
2257  }
2258 
2259  QSqlTableModel regions(nullptr, db);
2261  regions.setTable("horizons");
2262  regions.select();
2263 
2264  QSqlQuery query(db);
2265 
2266  for (int i = 0; i < regions.rowCount(); ++i)
2267  {
2268  QSqlRecord record = regions.record(i);
2269  QString tableQuery = QString("DROP TABLE %1").arg(record.value("name").toString());
2270  if (!query.exec(tableQuery))
2271  qCWarning(KSTARS) << query.lastError().text();
2272  }
2273 
2274  regions.removeRows(0, regions.rowCount());
2275  regions.submitAll();
2276 
2277  regions.clear();
2278  return true;
2279 }
2280 
2281 bool KSUserDB::AddHorizon(ArtificialHorizonEntity *horizon)
2282 {
2283  auto db = QSqlDatabase::database(m_ConnectionName);
2284  if (!db.isValid())
2285  {
2286  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2287  return false;
2288  }
2289 
2290  QSqlTableModel regions(nullptr, db);
2291  regions.setTable("horizons");
2292 
2293  regions.select();
2294  QString tableName = QString("horizon_%1").arg(regions.rowCount() + 1);
2295 
2296  regions.insertRow(0);
2297  regions.setData(regions.index(0, 1), tableName);
2298  regions.setData(regions.index(0, 2), horizon->region());
2299  int flags = 0;
2300  if (horizon->enabled()) flags |= 0x1;
2301  if (horizon->ceiling()) flags |= 0x2;
2302  regions.setData(regions.index(0, 3), flags);
2303  regions.submitAll();
2304  regions.clear();
2305 
2306  QString tableQuery = QString("CREATE TABLE %1 (Az REAL NOT NULL, Alt REAL NOT NULL)").arg(tableName);
2307  QSqlQuery query(db);
2308  query.exec(tableQuery);
2309 
2310  QSqlTableModel points(nullptr, db);
2311 
2312  points.setTable(tableName);
2313 
2314  SkyList *skyList = horizon->list()->points();
2315 
2316  for (const auto &item : *skyList)
2317  {
2318  points.select();
2319  QSqlRecord rec(points.record());
2320 
2321  rec.setValue("Az", item->az().Degrees());
2322  rec.setValue("Alt", item->alt().Degrees());
2323  points.insertRecord(-1, rec);
2324  }
2325 
2326  points.submitAll();
2327  points.clear();
2328  return true;
2329 }
2330 
2331 void KSUserDB::CreateImageOverlayTableIfNecessary()
2332 {
2333  auto db = QSqlDatabase::database(m_ConnectionName);
2334  QString command = "CREATE TABLE IF NOT EXISTS imageOverlays ( "
2335  "id INTEGER DEFAULT NULL PRIMARY KEY AUTOINCREMENT, "
2336  "filename TEXT NOT NULL,"
2337  "enabled INTEGER DEFAULT 0,"
2338  "nickname TEXT DEFAULT NULL,"
2339  "status INTEGER DEFAULT 0,"
2340  "orientation REAL DEFAULT 0.0,"
2341  "ra REAL DEFAULT 0.0,"
2342  "dec REAL DEFAULT 0.0,"
2343  "pixelsPerArcsec REAL DEFAULT 0.0,"
2344  "eastToTheRight INTEGER DEFAULT 0,"
2345  "width INTEGER DEFAULT 0,"
2346  "height INTEGER DEFAULT 0)";
2347  QSqlQuery query(db);
2348  if (!query.exec(command))
2349  {
2350  qCDebug(KSTARS) << query.lastError();
2351  qCDebug(KSTARS) << query.executedQuery();
2352  }
2353 }
2354 
2356 {
2357  CreateImageOverlayTableIfNecessary();
2358  auto db = QSqlDatabase::database(m_ConnectionName);
2359  if (!db.isValid())
2360  {
2361  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2362  return false;
2363  }
2364 
2365  QSqlTableModel overlays(nullptr, db);
2366  overlays.setTable("imageOverlays");
2367  overlays.setFilter("id >= 1");
2368  overlays.select();
2369  overlays.removeRows(0, overlays.rowCount());
2370  overlays.submitAll();
2371 
2372  QSqlQuery query(db);
2373  QString dropQuery = QString("DROP TABLE imageOverlays");
2374  if (!query.exec(dropQuery))
2375  qCWarning(KSTARS) << query.lastError().text();
2376 
2377  return true;
2378 }
2379 
2380 bool KSUserDB::AddImageOverlay(const ImageOverlay &overlay)
2381 {
2382  CreateImageOverlayTableIfNecessary();
2383  auto db = QSqlDatabase::database(m_ConnectionName);
2384  if (!db.isValid())
2385  {
2386  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2387  return false;
2388  }
2389 
2390  QSqlTableModel overlays(nullptr, db);
2391  overlays.setTable("imageOverlays");
2392  overlays.setFilter("filename LIKE \'" + overlay.m_Filename + "\'");
2393  overlays.select();
2394 
2395  if (overlays.rowCount() > 0)
2396  {
2397  QSqlRecord record = overlays.record(0);
2398  record.setValue("filename", overlay.m_Filename);
2399  record.setValue("enabled", static_cast<int>(overlay.m_Enabled));
2400  record.setValue("nickname", overlay.m_Nickname);
2401  record.setValue("status", static_cast<int>(overlay.m_Status));
2402  record.setValue("orientation", overlay.m_Orientation);
2403  record.setValue("ra", overlay.m_RA);
2404  record.setValue("dec", overlay.m_DEC);
2405  record.setValue("pixelsPerArcsec", overlay.m_ArcsecPerPixel);
2406  record.setValue("eastToTheRight", static_cast<int>(overlay.m_EastToTheRight));
2407  record.setValue("width", overlay.m_Width);
2408  record.setValue("height", overlay.m_Height);
2409  overlays.setRecord(0, record);
2410  overlays.submitAll();
2411  }
2412  else
2413  {
2414  int row = 0;
2415  overlays.insertRows(row, 1);
2416 
2417  overlays.setData(overlays.index(row, 1), overlay.m_Filename); // row,0 is autoincerement ID
2418  overlays.setData(overlays.index(row, 2), static_cast<int>(overlay.m_Enabled));
2419  overlays.setData(overlays.index(row, 3), overlay.m_Nickname);
2420  overlays.setData(overlays.index(row, 4), static_cast<int>(overlay.m_Status));
2421  overlays.setData(overlays.index(row, 5), overlay.m_Orientation);
2422  overlays.setData(overlays.index(row, 6), overlay.m_RA);
2423  overlays.setData(overlays.index(row, 7), overlay.m_DEC);
2424  overlays.setData(overlays.index(row, 8), overlay.m_ArcsecPerPixel);
2425  overlays.setData(overlays.index(row, 9), static_cast<int>(overlay.m_EastToTheRight));
2426  overlays.setData(overlays.index(row, 10), overlay.m_Width);
2427  overlays.setData(overlays.index(row, 11), overlay.m_Height);
2428  overlays.submitAll();
2429  }
2430  return true;
2431 }
2432 
2434 {
2435  CreateImageOverlayTableIfNecessary();
2436  auto db = QSqlDatabase::database(m_ConnectionName);
2437  if (!db.isValid())
2438  {
2439  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2440  return false;
2441  }
2442 
2443  imageOverlayList->clear();
2444  QSqlTableModel overlays(nullptr, db);
2445  overlays.setTable("imageOverlays");
2446  overlays.select();
2447 
2448  for (int i = 0; i < overlays.rowCount(); ++i)
2449  {
2450  QSqlRecord record = overlays.record(i);
2451 
2452  const QString filename = record.value("filename").toString();
2453  const bool enabled = static_cast<bool>(record.value("enabled").toInt());
2454  const QString nickname = record.value("nickname").toString();
2455  const ImageOverlay::Status status
2456  = static_cast<ImageOverlay::Status>(record.value("status").toInt());
2457  const double orientation = record.value("orientation").toDouble();
2458  const double ra = record.value("ra").toDouble();
2459  const double dec = record.value("dec").toDouble();
2460  const double pixelsPerArcsec = record.value("pixelsPerArcsec").toDouble();
2461  const bool eastToTheRight = static_cast<bool>(record.value("eastToTheRight").toInt());
2462  const int width = record.value("width").toInt();
2463  const int height = record.value("height").toInt();
2464  ImageOverlay o(filename, enabled, nickname, status, orientation, ra, dec, pixelsPerArcsec,
2465  eastToTheRight, width, height);
2466  imageOverlayList->append(o);
2467  }
2468 
2469  overlays.clear();
2470  return true;
2471 }
2472 
2473 int KSUserDB::AddProfile(const QString &name)
2474 {
2475  auto db = QSqlDatabase::database(m_ConnectionName);
2476  if (!db.isValid())
2477  {
2478  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2479  return -1;
2480  }
2481 
2482  int id = -1;
2483 
2484  QSqlQuery query(db);
2485  bool rc = query.exec(QString("INSERT INTO profile (name) VALUES('%1')").arg(name));
2486 
2487  if (rc == false)
2488  qCWarning(KSTARS) << query.lastQuery() << query.lastError().text();
2489  else
2490  id = query.lastInsertId().toInt();
2491 
2492  return id;
2493 }
2494 
2495 bool KSUserDB::DeleteProfile(const QSharedPointer<ProfileInfo> &pi)
2496 {
2497  auto db = QSqlDatabase::database(m_ConnectionName);
2498  if (!db.isValid())
2499  {
2500  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2501  return false;
2502  }
2503 
2504  QSqlQuery query(db);
2505  bool rc;
2506 
2507  rc = query.exec("DELETE FROM profile WHERE id=" + QString::number(pi->id));
2508 
2509  if (rc == false)
2510  qCWarning(KSTARS) << query.lastQuery() << query.lastError().text();
2511 
2512 
2513 
2514  return rc;
2515 }
2516 
2517 bool KSUserDB::PurgeProfile(const QSharedPointer<ProfileInfo> &pi)
2518 {
2519  auto db = QSqlDatabase::database(m_ConnectionName);
2520  if (!db.isValid())
2521  {
2522  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2523  return false;
2524  }
2525 
2526  QSqlQuery query(db);
2527  bool rc;
2528 
2529  rc = query.exec("DELETE FROM profile WHERE id=" + QString::number(pi->id));
2530  if (rc == false)
2531  qCWarning(KSTARS) << query.lastQuery() << query.lastError().text();
2532  rc = query.exec("DELETE FROM profilesettings WHERE profile=" + QString::number(pi->id));
2533  if (rc == false)
2534  qCWarning(KSTARS) << query.lastQuery() << query.lastError().text();
2535  rc = query.exec("DELETE FROM opticaltrainsettings WHERE opticaltrain IN (select id FROM opticaltrains WHERE profile=" +
2536  QString::number(pi->id) + ")");
2537  if (rc == false)
2538  qCWarning(KSTARS) << query.lastQuery() << query.lastError().text();
2539  rc = query.exec("DELETE FROM opticaltrains WHERE profile=" + QString::number(pi->id));
2540  if (rc == false)
2541  qCWarning(KSTARS) << query.lastQuery() << query.lastError().text();
2542 
2543  return rc;
2544 }
2545 
2546 bool KSUserDB::SaveProfile(const QSharedPointer<ProfileInfo> &pi)
2547 {
2548  auto db = QSqlDatabase::database(m_ConnectionName);
2549  if (!db.isValid())
2550  {
2551  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2552  return false;
2553  }
2554 
2555  // Remove all drivers
2556  DeleteProfileDrivers(pi);
2557 
2558  QSqlQuery query(db);
2559 
2560  // Clear data
2561  if (!query.exec(QString("UPDATE profile SET "
2562  "host=null,port=null,city=null,province=null,country=null,indiwebmanagerport=NULL,"
2563  "autoconnect=NULL,portselector=NULL,indihub=0 WHERE id=%1")
2564  .arg(pi->id)))
2565  qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2566 
2567  // Update Name
2568  if (!query.exec(QString("UPDATE profile SET name='%1' WHERE id=%2").arg(pi->name).arg(pi->id)))
2569  qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2570 
2571  // Update Remote Data
2572  if (pi->host.isEmpty() == false)
2573  {
2574  if (!query.exec(
2575  QString("UPDATE profile SET host='%1',port=%2 WHERE id=%3").arg(pi->host).arg((pi->port)).arg(pi->id)))
2576  qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2577 
2578  if (pi->INDIWebManagerPort != -1)
2579  {
2580  if (!query.exec(QString("UPDATE profile SET indiwebmanagerport='%1' WHERE id=%2")
2581  .arg(pi->INDIWebManagerPort)
2582  .arg(pi->id)))
2583  qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2584  }
2585  }
2586 
2587  // Update City Info
2588  if (pi->city.isEmpty() == false)
2589  {
2590  if (!query.exec(QString("UPDATE profile SET city='%1',province='%2',country='%3' WHERE id=%4")
2591  .arg(pi->city, pi->province, pi->country)
2592  .arg(pi->id)))
2593  {
2594  qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2595  }
2596  }
2597 
2598  // Update Auto Connect Info
2599  if (!query.exec(QString("UPDATE profile SET autoconnect=%1 WHERE id=%2").arg(pi->autoConnect ? 1 : 0).arg(pi->id)))
2600  qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2601 
2602  // Update Port Selector Info
2603  if (!query.exec(QString("UPDATE profile SET portselector=%1 WHERE id=%2").arg(pi->portSelector ? 1 : 0).arg(pi->id)))
2604  qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2605 
2606  // Update Guide Application Info
2607  if (!query.exec(QString("UPDATE profile SET guidertype=%1 WHERE id=%2").arg(pi->guidertype).arg(pi->id)))
2608  qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2609 
2610  // Update INDI Hub
2611  if (!query.exec(QString("UPDATE profile SET indihub=%1 WHERE id=%2").arg(pi->indihub).arg(pi->id)))
2612  qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2613 
2614  // If using external guider
2615  if (pi->guidertype != 0)
2616  {
2617  if (!query.exec(QString("UPDATE profile SET guiderhost='%1' WHERE id=%2").arg(pi->guiderhost).arg(pi->id)))
2618  qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2619  if (!query.exec(QString("UPDATE profile SET guiderport=%1 WHERE id=%2").arg(pi->guiderport).arg(pi->id)))
2620  qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2621  }
2622 
2623  // Update remote drivers
2624  if (!query.exec(QString("UPDATE profile SET remotedrivers='%1' WHERE id=%2").arg(pi->remotedrivers).arg(pi->id)))
2625  qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2626 
2627  // Update scripts
2628  if (!query.exec(QString("UPDATE profile SET scripts='%1' WHERE id=%2").arg(QString::fromLocal8Bit(pi->scripts)).arg(
2629  pi->id)))
2630  qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2631 
2632  QMapIterator<QString, QString> i(pi->drivers);
2633  while (i.hasNext())
2634  {
2635  i.next();
2636  if (!query.exec(QString("INSERT INTO driver (label, role, profile) VALUES('%1','%2',%3)")
2637  .arg(i.value(), i.key())
2638  .arg(pi->id)))
2639  {
2640  qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2641  }
2642  }
2643 
2644  /*if (pi->customDrivers.isEmpty() == false && !query.exec(QString("INSERT INTO custom_driver (drivers, profile) VALUES('%1',%2)").arg(pi->customDrivers).arg(pi->id)))
2645  qDebug() << query.lastQuery() << query.lastError().text();*/
2646 
2647 
2648  return true;
2649 }
2650 
2652 {
2653  auto db = QSqlDatabase::database(m_ConnectionName);
2654  if (!db.isValid())
2655  {
2656  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2657  return false;
2658  }
2659 
2660  profiles.clear();
2661  QSqlTableModel profile(nullptr, db);
2662  profile.setTable("profile");
2663  profile.select();
2664 
2665  for (int i = 0; i < profile.rowCount(); ++i)
2666  {
2667  QSqlRecord record = profile.record(i);
2668 
2669  int id = record.value("id").toInt();
2670  QString name = record.value("name").toString();
2671  QSharedPointer<ProfileInfo> pi(new ProfileInfo(id, name));
2672 
2673  // Add host and port
2674  pi->host = record.value("host").toString();
2675  pi->port = record.value("port").toInt();
2676 
2677  // City info
2678  pi->city = record.value("city").toString();
2679  pi->province = record.value("province").toString();
2680  pi->country = record.value("country").toString();
2681 
2682  pi->INDIWebManagerPort = record.value("indiwebmanagerport").toInt();
2683  pi->autoConnect = (record.value("autoconnect").toInt() == 1);
2684  pi->portSelector = (record.value("portselector").toInt() == 1);
2685 
2686  pi->indihub = record.value("indihub").toInt();
2687 
2688  pi->guidertype = record.value("guidertype").toInt();
2689  if (pi->guidertype != 0)
2690  {
2691  pi->guiderhost = record.value("guiderhost").toString();
2692  pi->guiderport = record.value("guiderport").toInt();
2693  }
2694 
2695  pi->remotedrivers = record.value("remotedrivers").toString();
2696 
2697  pi->scripts = record.value("scripts").toByteArray();
2698 
2699  GetProfileDrivers(pi);
2700 
2701  profiles.append(std::move(pi));
2702  }
2703 
2704  return true;
2705 }
2706 
2707 bool KSUserDB::GetProfileDrivers(const QSharedPointer<ProfileInfo> &pi)
2708 {
2709  auto db = QSqlDatabase::database(m_ConnectionName);
2710  if (!db.isValid())
2711  {
2712  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2713  return false;
2714  }
2715 
2716  QSqlTableModel driver(nullptr, db);
2717  driver.setTable("driver");
2718  driver.setFilter("profile=" + QString::number(pi->id));
2719  if (driver.select() == false)
2720  qCWarning(KSTARS) << "Driver select error:" << driver.lastError().text();
2721 
2722  for (int i = 0; i < driver.rowCount(); ++i)
2723  {
2724  QSqlRecord record = driver.record(i);
2725  QString label = record.value("label").toString();
2726  QString role = record.value("role").toString();
2727 
2728  pi->drivers[role] = label;
2729  }
2730 
2731  driver.clear();
2732  return true;
2733 }
2734 
2735 /*void KSUserDB::GetProfileCustomDrivers(ProfileInfo* pi)
2736 {
2737  userdb_.open();
2738  QSqlTableModel custom_driver(0, userdb_);
2739  custom_driver.setTable("driver");
2740  custom_driver.setFilter("profile=" + QString::number(pi->id));
2741  if (custom_driver.select() == false)
2742  qDebug() << Q_FUNC_INFO << "custom driver select error: " << custom_driver.query().lastQuery() << custom_driver.lastError().text();
2743 
2744  QSqlRecord record = custom_driver.record(0);
2745  pi->customDrivers = record.value("drivers").toString();
2746 
2747  custom_driver.clear();
2748  userdb_.close();
2749 }*/
2750 
2751 bool KSUserDB::DeleteProfileDrivers(const QSharedPointer<ProfileInfo> &pi)
2752 {
2753  auto db = QSqlDatabase::database(m_ConnectionName);
2754  if (!db.isValid())
2755  {
2756  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2757  return false;
2758  }
2759 
2760  QSqlQuery query(db);
2761 
2762  /*if (!query.exec("DELETE FROM custom_driver WHERE profile=" + QString::number(pi->id)))
2763  qDebug() << Q_FUNC_INFO << query.lastQuery() << query.lastError().text();*/
2764 
2765  if (!query.exec("DELETE FROM driver WHERE profile=" + QString::number(pi->id)))
2766  qCWarning(KSTARS) << query.executedQuery() << query.lastError().text();
2767 
2768  return true;
2769 }
2770 
2771 /*
2772  * DSLR Lens Section
2773 */
2774 bool KSUserDB::AddDSLRLens(const QString &model, const QString &vendor, const double focalLength, const double focalRatio)
2775 {
2776  auto db = QSqlDatabase::database(m_ConnectionName);
2777  if (!db.isValid())
2778  {
2779  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2780  return false;
2781  }
2782 
2783  QSqlTableModel equip(nullptr, db);
2784  equip.setTable("dslrlens");
2785 
2786  QSqlRecord record = equip.record();
2787  record.setValue("Vendor", vendor);
2788  record.setValue("Model", model);
2789  record.setValue("FocalLength", focalLength);
2790  record.setValue("FocalRatio", focalRatio);
2791 
2792  if (equip.insertRecord(-1, record) == false)
2793  qCritical() << __FUNCTION__ << equip.lastError();
2794  equip.submitAll();
2795  equip.clear();
2796 
2797  return true;
2798 
2799 }
2800 
2801 bool KSUserDB::AddDSLRLens(const QString &model, const QString &vendor, const double focalLength, const double focalRatio,
2802  const QString &id)
2803 {
2804  auto db = QSqlDatabase::database(m_ConnectionName);
2805  if (!db.isValid())
2806  {
2807  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2808  return false;
2809  }
2810 
2811  QSqlTableModel equip(nullptr, db);
2812  equip.setTable("dslrlens");
2813  equip.setFilter("id = " + id);
2814  equip.select();
2815 
2816  if (equip.rowCount() > 0)
2817  {
2818  QSqlRecord record = equip.record(0);
2819  record.setValue("Vendor", vendor);
2820  record.setValue("Model", model);
2821  record.setValue("FocalLength", focalLength);
2822  record.setValue("FocalRatio", focalRatio);
2823  equip.setRecord(0, record);
2824  equip.submitAll();
2825  }
2826 
2827  return true;
2828 }
2829 
2830 #ifndef KSTARS_LITE
2832 {
2833  dslrlens_list.clear();
2834 
2835  auto db = QSqlDatabase::database(m_ConnectionName);
2836  if (!db.isValid())
2837  {
2838  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2839  return false;
2840  }
2841 
2842  QSqlTableModel equip(nullptr, db);
2843  equip.setTable("dslrlens");
2844  equip.select();
2845 
2846  for (int i = 0; i < equip.rowCount(); ++i)
2847  {
2848  QSqlRecord record = equip.record(i);
2849  QString id = record.value("id").toString();
2850  QString vendor = record.value("Vendor").toString();
2851  QString model = record.value("Model").toString();
2852  double focalLength = record.value("FocalLength").toDouble();
2853  double focalRatio = record.value("FocalRatio").toDouble();
2854  OAL::DSLRLens *o = new OAL::DSLRLens(id, model, vendor, focalLength, focalRatio);
2855  dslrlens_list.append(o);
2856  }
2857 
2858  equip.clear();
2859 
2860  return true;
2861 }
2862 #endif
2863 
2864 bool KSUserDB::getOpticalElementByID(int id, QJsonObject &element)
2865 {
2866  // Get all OAL equipment filter list
2867  QList<OAL::Scope *> scopeList;
2868  QList<OAL::DSLRLens *> dslrlensList;
2869  KStarsData::Instance()->userdb()->GetAllScopes(scopeList);
2870  KStarsData::Instance()->userdb()->GetAllDSLRLenses(dslrlensList);
2871 
2872  for (auto &oneScope : scopeList)
2873  {
2874  if (oneScope->id().toInt() == id)
2875  {
2876  element = oneScope->toJson();
2877  return true;
2878  }
2879  }
2880 
2881  for (auto &oneLens : dslrlensList)
2882  {
2883  if (oneLens->id().toInt() == id)
2884  {
2885  element = oneLens->toJson();
2886  return true;
2887  }
2888  }
2889 
2890  return false;
2891 }
2892 
2894 {
2895  // Get all OAL equipment filter list
2896  QList<OAL::Scope *> scopeList;
2897  QList<OAL::DSLRLens *> dslrlensList;
2898  KStarsData::Instance()->userdb()->GetAllScopes(scopeList);
2899  KStarsData::Instance()->userdb()->GetAllDSLRLenses(dslrlensList);
2900 
2901  if (!scopeList.empty())
2902  {
2903  element = scopeList.last()->toJson();
2904  return true;
2905  }
2906 
2907  if (!dslrlensList.empty())
2908  {
2909  element = dslrlensList.last()->toJson();
2910  return true;
2911  }
2912 
2913  return false;
2914 }
2915 
2916 bool KSUserDB::getOpticalElementByName(const QString &name, QJsonObject &element)
2917 {
2918  // Get all OAL equipment filter list
2919  QList<OAL::Scope *> scopeList;
2920  QList<OAL::DSLRLens *> dslrlensList;
2921  KStarsData::Instance()->userdb()->GetAllScopes(scopeList);
2922  KStarsData::Instance()->userdb()->GetAllDSLRLenses(dslrlensList);
2923 
2924  for (auto &oneScope : scopeList)
2925  {
2926  if (oneScope->name() == name)
2927  {
2928  element = oneScope->toJson();
2929  return true;
2930  }
2931  }
2932 
2933  for (auto &oneLens : dslrlensList)
2934  {
2935  if (oneLens->name() == name)
2936  {
2937  element = oneLens->toJson();
2938  return true;
2939  }
2940  }
2941 
2942  return false;
2943 }
2944 
2945 QStringList KSUserDB::getOpticalElementNames()
2946 {
2947  QStringList names;
2948 
2949  // Get all OAL equipment filter list
2950  QList<OAL::Scope *> scopeList;
2951  QList<OAL::DSLRLens *> dslrlensList;
2952  KStarsData::Instance()->userdb()->GetAllScopes(scopeList);
2953  KStarsData::Instance()->userdb()->GetAllDSLRLenses(dslrlensList);
2954 
2955  for (auto &oneValue : scopeList)
2956  names << oneValue->name();
2957 
2958  for (auto &oneValue : dslrlensList)
2959  names << oneValue->name();
2960 
2961  return names;
2962 }
2963 
2964 void KSUserDB::AddProfileSettings(uint32_t profile, const QByteArray &settings)
2965 {
2966  auto db = QSqlDatabase::database(m_ConnectionName);
2967  if (!db.isValid())
2968  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2969 
2970  QSqlTableModel profileSettings(nullptr, db);
2971  profileSettings.setTable("profilesettings");
2972  profileSettings.select();
2973 
2974  QSqlRecord record = profileSettings.record();
2975  record.setValue("profile", profile);
2976  record.setValue("settings", settings);
2977  profileSettings.insertRecord(-1, record);
2978 
2979  if (!profileSettings.submitAll())
2980  qCWarning(KSTARS) << profileSettings.lastError();
2981 
2982 
2983 }
2984 
2985 void KSUserDB::UpdateProfileSettings(uint32_t profile, const QByteArray &settings)
2986 {
2987  auto db = QSqlDatabase::database(m_ConnectionName);
2988  if (!db.isValid())
2989  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
2990 
2991  QSqlTableModel profileSettings(nullptr, db);
2992  profileSettings.setTable("profilesettings");
2993  profileSettings.setFilter(QString("profile=%1").arg(profile));
2994  profileSettings.select();
2995 
2996  QSqlRecord record = profileSettings.record(0);
2997  record.setValue("settings", settings);
2998  profileSettings.setRecord(0, record);
2999 
3000  if (!profileSettings.submitAll())
3001  qCWarning(KSTARS) << profileSettings.lastError();
3002 }
3003 
3004 
3005 void KSUserDB::DeleteProfileSettings(uint32_t profile)
3006 {
3007  auto db = QSqlDatabase::database(m_ConnectionName);
3008  if (!db.isValid())
3009  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
3010 
3011  QSqlTableModel profileSettings(nullptr, db);
3012  profileSettings.setTable("profilesettings");
3013  profileSettings.setFilter(QString("profile=%1").arg(profile));
3014 
3015  profileSettings.select();
3016  profileSettings.removeRows(0, profileSettings.rowCount() - 1);
3017  profileSettings.submitAll();
3018 }
3019 
3020 bool KSUserDB::GetProfileSettings(uint32_t profile, QVariantMap &settings)
3021 {
3022  auto db = QSqlDatabase::database(m_ConnectionName);
3023  if (!db.isValid())
3024  {
3025  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
3026  return false;
3027  }
3028 
3029  settings.clear();
3030 
3031  QSqlTableModel profileSettings(nullptr, db);
3032  profileSettings.setTable("profilesettings");
3033  profileSettings.setFilter(QString("profile=%1").arg(profile));
3034  profileSettings.select();
3035 
3036  if (profileSettings.rowCount() > 0)
3037  {
3038  QSqlRecord record = profileSettings.record(0);
3039  auto settingsField = record.value("settings").toByteArray();
3040  QJsonParseError parserError;
3041  auto doc = QJsonDocument::fromJson(settingsField, &parserError);
3042  if (parserError.error == QJsonParseError::NoError)
3043  {
3044  settings = doc.object().toVariantMap();
3045 
3046  return true;
3047  }
3048  }
3049 
3050  return false;
3051 }
3052 
3053 bool KSUserDB::AddOpticalTrainSettings(uint32_t train, const QByteArray &settings)
3054 {
3055  auto db = QSqlDatabase::database(m_ConnectionName);
3056  if (!db.isValid())
3057  {
3058  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
3059  return false;
3060  }
3061 
3062  QSqlTableModel OpticalTrainSettings(nullptr, db);
3063  OpticalTrainSettings.setTable("opticaltrainsettings");
3064  OpticalTrainSettings.select();
3065 
3066  QSqlRecord record = OpticalTrainSettings.record();
3067  record.setValue("opticaltrain", train);
3068  record.setValue("settings", settings);
3069  OpticalTrainSettings.insertRecord(-1, record);
3070 
3071  if (!OpticalTrainSettings.submitAll())
3072  {
3073  qCWarning(KSTARS) << OpticalTrainSettings.lastError();
3074  return false;
3075  }
3076 
3077  return true;
3078 }
3079 
3080 bool KSUserDB::UpdateOpticalTrainSettings(uint32_t train, const QByteArray &settings)
3081 {
3082  auto db = QSqlDatabase::database(m_ConnectionName);
3083  if (!db.isValid())
3084  {
3085  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
3086  return false;
3087  }
3088 
3089  QSqlTableModel OpticalTrainSettings(nullptr, db);
3090  OpticalTrainSettings.setTable("opticaltrainsettings");
3091  OpticalTrainSettings.setFilter(QString("opticaltrain=%1").arg(train));
3092  OpticalTrainSettings.select();
3093 
3094  QSqlRecord record = OpticalTrainSettings.record(0);
3095  record.setValue("settings", settings);
3096  OpticalTrainSettings.setRecord(0, record);
3097 
3098  if (!OpticalTrainSettings.submitAll())
3099  qCWarning(KSTARS) << OpticalTrainSettings.lastError();
3100 
3101  return true;
3102 }
3103 
3104 bool KSUserDB::DeleteOpticalTrainSettings(uint32_t train)
3105 {
3106  auto db = QSqlDatabase::database(m_ConnectionName);
3107  if (!db.isValid())
3108  {
3109  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
3110  return false;
3111  }
3112 
3113  QSqlQuery query(db);
3114  return query.exec(QString("DELETE FROM opticaltrainsettings WHERE opticaltrain=%1").arg(train));
3115 }
3116 
3117 bool KSUserDB::GetOpticalTrainSettings(uint32_t train, QVariantMap &settings)
3118 {
3119  auto db = QSqlDatabase::database(m_ConnectionName);
3120  if (!db.isValid())
3121  {
3122  qCCritical(KSTARS) << "Failed to open database:" << db.lastError();
3123  return false;
3124  }
3125 
3126  settings.clear();
3127 
3128  QSqlTableModel OpticalTrainSettings(nullptr, db);
3129  OpticalTrainSettings.setTable("OpticalTrainsettings");
3130  OpticalTrainSettings.setFilter(QString("opticaltrain=%1").arg(train));
3131  OpticalTrainSettings.select();
3132 
3133  if (OpticalTrainSettings.rowCount() > 0)
3134  {
3135  QSqlRecord record = OpticalTrainSettings.record(0);
3136  auto settingsField = record.value("settings").toByteArray();
3137  QJsonParseError parserError;
3138  auto doc = QJsonDocument::fromJson(settingsField, &parserError);
3139  if (parserError.error == QJsonParseError::NoError)
3140  {
3141  settings = doc.object().toVariantMap();
3142 
3143  return true;
3144  }
3145  }
3146 
3147  return false;
3148 }
void append(const T &value)
virtual void clear() override
std::optional< QSqlQuery > query(const QString &queryStatement)
bool UpdateOpticalTrain(const QVariantMap &oneTrain, int id)
Update an existing optical train.
Definition: ksuserdb.cpp:951
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
bool GetAllEyepieces(QList< OAL::Eyepiece * > &m_eyepieceList)
Populate the reference passed with all eyepieces.
Definition: ksuserdb.cpp:1645
QString number(int n, int base)
QStringRef value(const QString &namespaceUri, const QString &name) const const
bool remove()
bool DeleteAllEquipment(const QString &type)
Erases the whole equipment table of given type.
Definition: ksuserdb.cpp:1445
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)
void clear()
void append(const T &value)
virtual void setEditStrategy(QSqlTableModel::EditStrategy strategy)
bool 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:1541
bool 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:678
bool insertRow(int row, const QModelIndex &parent)
KSUserDB * userdb()
Definition: kstarsdata.h:215
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:651
bool isEndElement() const const
bool DeleteDarkFrame(const QString &filename)
KSUserDB::DeleteDarkFrame Delete from database a dark frame record that matches the filename field.
Definition: ksuserdb.cpp:771
bool AddImageOverlay(const ImageOverlay &overlay)
Adds a new image overlay row into the database.
Definition: ksuserdb.cpp:2380
void append(const QSqlField &field)
QVariant value(int index) const const
bool exists() const const
bool GetOpticalTrains(uint32_t profileID, QList< QVariantMap > &opticalTrains)
Populate the reference passed with all optical trains.
Definition: ksuserdb.cpp:1007
bool GetProfileSettings(uint32_t profile, QVariantMap &settings)
Populate the reference passed with settings for one paritcular profile.
Definition: ksuserdb.cpp:3020
bool Initialize()
Initialize KStarsDB while running splash screen.
Definition: ksuserdb.cpp:43
bool GetAllFilters(QList< OAL::Filter * > &m_filterList)
Populate the reference passed with all filters.
Definition: ksuserdb.cpp:1864
QStringRef name() const const
bool UpdateDarkFrame(const QVariantMap &oneFrame)
KSUserDB::UpdateDarkFrame Updates an existing dark frame record in the data, replace all values match...
Definition: ksuserdb.cpp:743
bool GetAllDSLRLenses(QList< OAL::DSLRLens * > &dslrlens_list)
updates the dslr list with all DSLR lenses from database List is cleared and then filled with content...
Definition: ksuserdb.cpp:2831
bool empty() const const
QMap::iterator end()
QSqlDatabase addDatabase(const QString &type, const QString &connectionName)
double toDouble(bool *ok) const const
bool GetAllProfiles(QList< QSharedPointer< ProfileInfo > > &profiles)
GetAllProfiles Return all profiles in a QList.
Definition: ksuserdb.cpp:2651
QString fromLocal8Bit(const char *str, int size)
bool DeleteEquipment(const QString &type, const QString &id)
Erase the equipment with given type and unique id Valid equipment types: "telescope",...
Definition: ksuserdb.cpp:1421
bool AddObserver(const QString &name, const QString &surname, const QString &contact)
Adds a new observer into the database.
Definition: ksuserdb.cpp:589
bool FindObserver(const QString &name, const QString &surname)
Returns the unique id of the user with given name & surname.
Definition: ksuserdb.cpp:628
bool AddFilter(const filterProperties *fp)
Add a new filter to the database.
Definition: ksuserdb.cpp:1779
bool AddHorizon(ArtificialHorizonEntity *horizon)
Adds a new artificial horizon row into the database.
Definition: ksuserdb.cpp:2281
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
virtual void setTable(const QString &tableName)
QXmlStreamReader::TokenType readNext()
virtual bool insertRows(int row, int count, const QModelIndex &parent) override
bool GetOpticalTrainSettings(uint32_t train, QVariantMap &settings)
Populate the reference passed with settings for one paritcular Train.
Definition: ksuserdb.cpp:3117
QString filePath() const const
int toInt(bool *ok) const const
int toInt(bool *ok, int base) const const
QString readElementText(QXmlStreamReader::ReadElementTextBehaviour behaviour)
QXmlStreamAttributes attributes() const const
QSqlError lastError() const const
double toDouble(bool *ok) const const
T & last()
QString & remove(int position, int n)
bool GetAllHorizons(QList< ArtificialHorizonEntity * > &horizonList)
Gets all the artificial horizon rows from the database.
Definition: ksuserdb.cpp:2190
QString label(StandardShortcut id)
Definition: lens.h:17
bool getLastOpticalElement(QJsonObject &element)
getLastOpticalElement Return last inserted scope or lens
Definition: ksuserdb.cpp:2893
bool AddDSLRLens(const QString &model, const QString &vendor, const double focalLength, const double focalRatio)
Appends the DSLR lens with given details in the database.
Definition: ksuserdb.cpp:2774
bool AddLens(const QString &vendor, const QString &model, const double &factor)
Add a new lens to the database.
Definition: ksuserdb.cpp:1685
QString text() const const
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
bool 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:1347
bool GetAllFlags(QList< QStringList > &flagList)
Returns a QList populated with all stored flags Order: const QString &ra, const QString &dec,...
Definition: ksuserdb.cpp:1377
bool AddOpticalTrain(const QVariantMap &oneTrain)
Add a new optical train to the database.
Definition: ksuserdb.cpp:916
QString filePath(const QString &fileName) const const
void setValue(int index, const QVariant &val)
bool AddScope(const QString &model, const QString &vendor, const QString &type, const double &aperture, const double &focalLength)
Appends the scope with given details in the database.
Definition: ksuserdb.cpp:1473
void clear()
bool DeleteAllFlags()
Erases all the flags from the database.
Definition: ksuserdb.cpp:1322
int count(const T &value) const const
QString fieldName(int index) const const
bool AddOpticalTrainSettings(uint32_t train, const QByteArray &settings)
Add new Train settings to the database.
Definition: ksuserdb.cpp:3053
bool AddEyepiece(const QString &vendor, const QString &model, const double &focalLength, const double &fov, const QString &fovunit)
Add new eyepiece to database.
Definition: ksuserdb.cpp:1581
bool isStartElement() const const
bool atEnd() const const
int count() const const
QSqlDatabase database(const QString &connectionName, bool open)
bool GetAllLenses(QList< OAL::Lens * > &m_lensList)
Populate the reference passed with all lenses.
Definition: ksuserdb.cpp:1741
virtual bool select()
bool GetAllImageOverlays(QList< ImageOverlay > *imageOverlayList)
Gets all the image overlay rows from the database.
Definition: ksuserdb.cpp:2433
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
bool AddDarkFrame(const QVariantMap &oneFrame)
KSUserDB::AddDarkFrame Saves a new dark frame data to the database.
Definition: ksuserdb.cpp:714
void AddProfileSettings(uint32_t profile, const QByteArray &settings)
Add new profile settings to the database.
Definition: ksuserdb.cpp:2964
QString toString() const const
bool DeleteAllHorizons()
Deletes all artificial horizon rows from the database.
Definition: ksuserdb.cpp:2250
bool DeleteAllImageOverlays()
Deletes all image overlay rows from the database.
Definition: ksuserdb.cpp:2355
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Oct 1 2023 04:02:41 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.