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

KDE's Doxygen guidelines are available online.