Kstars

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

KDE's Doxygen guidelines are available online.