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

KDE's Doxygen guidelines are available online.