YATiSh
Yet Another TIme SHeet
yatishDBsqlite.cpp
Go to the documentation of this file.
1 /********************************************************************
2  * Name: yatishDBsqlite.cpp
3  * Purpose: Implements the sqlite controller
4  * Author: Nicolas PĂ©renne (nicolas.perenne@eif-services.eu)
5  * Created: 2020-03-09
6  * Copyright: EIF-services (https://www.eif-services.eu/yatish)
7  * License: GPLv3
8  ********************************************************************/
9 
10 #include "yatishDBsqlite.h"
11 
17  filter = wxEmptyString;
18  limitRow = false; rowLimit = 100;
19  wxASSERT_MSG (masterDB == nullptr, "There can be only one instance of yatishDBsqlite.");
20 #ifdef NDEBUG
21  wxString databasePath = wxStandardPaths::Get().GetUserLocalDataDir() + wxFILE_SEP_PATH + "yatish.sqlite";
22  databasePath.Replace ("\\", "\\\\" ); // need to escape (Windows) anti-slashes
23 #else
24  wxString databasePath = "yatish.sqlite";
25 #endif
26  masterDB = GetDatabase ("[SQLite]\ndatabase=" + databasePath);
27  if (!masterDB) {
28  wxMessageBox (_("You are probably using Yatish for the first time...\n"
29  "Please ignore error messages and read\n"
30  "\"Getting started\" in the User guide (F1)"),
31  _("Startup procedure completed?"), wxOK);
32  return;
33  }
34  try {
35  if (masterDB->GetTypeName() != "SQLITE")
36  throw ( wxDatabaseException (-4, _("Master DB must be SQLite") ) );
37  if ( !TablesOk (masterDB) )
38  throw ( wxDatabaseException (-5, _("Yatish tables not found (SQLite)") ) );
39  masterDB->RunQuery ("PRAGMA foreign_keys = ON;");
40  }
41  catch (wxDatabaseException& e) {
42  wxLogError ( "[%d] %s", e.GetErrorCode(), e.GetErrorMessage() );
43  masterDB->Close();
44  delete masterDB;
45  masterDB = nullptr;
46  }
47 }
48 
50  if (!masterDB) return;
51  StopTimeslot(); // in case yatish is closed before stop button is pressed
52  masterDB->Close();
53  delete masterDB;
54 }
55 
62 bool yatishDBsqlite::FillChoice (wxChoice * choices, tableID tid) {
63  if (!masterDB) return false;
64  wxArrayLong * ids;
65  wxString sql ("SELECT id,name FROM yatish_");
66  switch (tid) {
67  case client_tid:
68  sql += "client WHERE sync <> 'D' ORDER BY name;";
69  ids = &clientIDs;
70  break;
71  case project_tid:
72  sql += "project WHERE sync <> 'D' ORDER BY name;";
73  ids = &projectIDs;
74  break;
75  case task_tid:
76  sql += "task WHERE sync <> 'D' ORDER BY name;";
77  ids = &taskIDs;
78  break;
79  case tool_tid:
80  sql += "tool WHERE sync <> 'D' ORDER BY name;";
81  ids = &toolIDs;
82  break;
83  default:
84  return false;
85  }
86  ids->Empty();
87  choices->Clear();
88  try {
89  wxDatabaseResultSet * results = masterDB->RunQueryWithResults (sql);
90  while ( results->Next() ) {
91  ids->Add ( results->GetResultLong (1) );
92  choices->Append ( results->GetResultString (2) );
93  }
94  masterDB->CloseResultSet (results);
95  }
96  CATCH (false)
97  ids->Shrink();
98  return true;
99 }
100 
109  if (!masterDB) return wxNOT_FOUND;
110  wxArrayLong * ids;
111  tableID refering_tid;
112  switch (tid) {
113  case client_tid:
114  ids = &clientIDs;
115  refering_tid = project_tid;
116  break;
117  case project_tid:
118  ids = &projectIDs;
119  refering_tid = activity_tid;
120  break;
121  case task_tid:
122  ids = &taskIDs;
123  refering_tid = activity_tid;
124  break;
125  case tool_tid:
126  ids = &toolIDs;
127  refering_tid = activity_tid;
128  break;
129  default:
130  return wxNOT_FOUND;
131  }
132  long refered_id;
133  try {
134  wxString sql;
135  sql.Printf ("SELECT %s_id FROM yatish_%s WHERE id = %ld;",
136  tableName[tid], tableName[refering_tid], id);
137  refered_id = masterDB->GetSingleResultLong (sql, 1);
138  }
139  CATCH (wxNOT_FOUND)
140  return ids->Index (refered_id);
141 }
142 
148 bool yatishDBsqlite::StartTimeslot (int project, int task, int tool) {
149  if (!masterDB) return false;
150  int projectID = projectIDs[project],
151  taskID = taskIDs[task],
152  toolID = toolIDs[tool];
153  wxString sql;
154  sql.Printf ("SELECT id FROM yatish_activity"
155  " WHERE project_id = %d AND task_id = %d AND tool_id = %d;",
156  projectID, taskID, toolID);
157  try {
158  wxDatabaseResultSet * results = masterDB->RunQueryWithResults (sql);
159  if ( !results->Next() ) {
160  wxString sql2;
161  sql2.Printf ("INSERT INTO yatish_activity (project_id,task_id,tool_id,sync)"
162  " VALUES (%d,%d,%d,'I');",
163  projectID, taskID, toolID);
164  masterDB->CloseResultSet (results);
165  masterDB->RunQuery (sql2);
166  results = masterDB->RunQueryWithResults (sql);
167  results->Next();
168  }
169  long activityID = results->GetResultLong (1);
170  masterDB->CloseResultSet (results);
171  sql.Printf ("INSERT INTO yatish_timeslot (start,activity_id,sync)"
172  " VALUES (datetime('now'),%ld,'I');", activityID); // datetime('now'): SQLite specific (UTC)
173  masterDB->RunQuery (sql);
174  results = masterDB->RunQueryWithResults ("SELECT id FROM yatish_timeslot WHERE stop IS NULL;");
175  results->Next(); // there should be one and only one...
176  currentTimeslotID = results->GetResultLong (1);
177  masterDB->CloseResultSet (results);
178  }
179  CATCH (false)
180  return true;
181 }
182 
187  if (!masterDB) return false;
188  try {
189  wxString sql;
190  sql.Printf ("UPDATE yatish_timeslot SET stop=datetime('now')"
191  " WHERE id = %ld AND stop IS NULL;", currentTimeslotID);
192  masterDB->RunQuery (sql);
193  }
194  CATCH (false)
195  return true;
196 }
197 
202  if (!masterDB) return -1;
203  int n;
204  try {
205  wxString sql ("SELECT id,COUNT(*) FROM yatish_timeslot WHERE stop IS NULL;");
206  currentTimeslotID = masterDB->GetSingleResultLong (sql, 1);
207  n = masterDB->GetSingleResultInt (sql, 2);
208  }
209  CATCH (-1)
210  return n;
211 }
212 
219 bool yatishDBsqlite::FillList (wxListCtrl * lst, tableID tid) {
220  if (!masterDB) return false;
221  int colmin, colmax = lst->GetColumnCount();
222  wxString sql ("SELECT ");
223  switch (tid) {
224  case client_tid:
225  if (colmax != 1) return false;
226  sql += "id,name FROM yatish_client WHERE sync <> 'D';";
227  break;
228  case project_tid:
229  if (colmax != 2) return false;
230  sql += "p.id,p.name,c.name FROM yatish_project AS p"
231  " INNER JOIN yatish_client AS c ON p.client_id = c.id"
232  " WHERE p.sync <> 'D'";
233  sql += filter;
234  sql += ";";
235  break;
236  case task_tid:
237  if (colmax != 1) return false;
238  sql += "id,name FROM yatish_task WHERE sync <> 'D';";
239  break;
240  case tool_tid:
241  if (colmax != 1) return false;
242  sql += "id,name FROM yatish_tool WHERE sync <> 'D';";
243  break;
244  case activity_tid:
245  if (colmax != 4) return false;
246  sql += "a.id,p.name,c.name,tk.name,tl.name"
247  " FROM (((yatish_activity AS a"
248  " INNER JOIN yatish_project AS p ON a.project_id = p.id)"
249  " INNER JOIN yatish_client AS c ON p.client_id = c.id)"
250  " INNER JOIN yatish_task AS tk ON a.task_id = tk.id)"
251  " INNER JOIN yatish_tool AS tl ON a.tool_id = tl.id"
252  " WHERE a.sync <> 'D'";
253  sql += filter;
254  sql += ";";
255  break;
256  case timeslot_tid:
257  if (colmax != 6) return false;
258  sql.Printf ("SELECT t.id,t.start,t.stop,p.name,c.name,tk.name,tl.name"
259  " FROM ((((yatish_timeslot AS t"
260  " INNER JOIN yatish_activity AS a ON t.activity_id = a.id)"
261  " INNER JOIN yatish_project AS p ON a.project_id = p.id)"
262  " INNER JOIN yatish_client AS c ON p.client_id = c.id)"
263  " INNER JOIN yatish_task AS tk ON a.task_id = tk.id)"
264  " INNER JOIN yatish_tool AS tl ON a.tool_id = tl.id"
265  " WHERE t.sync <> 'D' AND t.start BETWEEN '%s' AND '%s'"
266  , firstDay, lastDay);
267  sql += filter;
268  if (limitRow)
269  sql += wxString::Format (" ORDER BY t.id DESC LIMIT %d;", rowLimit);
270  else
271  sql += " ORDER BY t.id DESC;";
272  break;
273  default:
274  return false;
275  }
276  // { for timeslot_tid only...
277  wxTimeSpan span;
278  slotCount = 0;
279  totalSpan = wxTimeSpan::Hours (0);
280  // }
281  try {
282  wxDatabaseResultSet * results = masterDB->RunQueryWithResults (sql);
283  long row = 0,
284  row_index; // appears to be necessary...
285  while ( results->Next() ) {
286  if (tid == timeslot_tid) {
287  wxDateTime start = results->GetResultDate (2), stop = results->GetResultDate (3);
288  start.MakeFromUTC();
289  // update first item of the row
290  row_index = lst->InsertItem ( row++, start.FormatISODate() );
291  if ( stop.IsValid() ) {
292  stop.MakeFromUTC();
293  span = stop - start;
294  slotCount++; totalSpan += span;
295  // update second item of the row
296  lst->SetItem ( row_index, 1, span.Format ("%H:%M:%S") );
297  }
298  colmin = 2;
299  } else {
300  // update first item of the row
301  row_index = lst->InsertItem ( row++, results->GetResultString (2) );
302  colmin = 1;
303  }
304  // update remaining items
305  for (int col = colmin; col < colmax; col++)
306  // +1 because wxDatabase indexes are 1-based, and +1 to skip the id
307  lst->SetItem ( row_index, col, results->GetResultString (col + 2) );
308  // store the SQL id of the row (which is not the row index)
309  lst->SetItemData ( row_index, results->GetResultLong (1) );
310  }
311  masterDB->CloseResultSet (results);
312  }
313  CATCH (false)
314  return true;
315 }
316 
322  if (!masterDB) return false;
323  wxString sql ("SELECT t.start,t.stop,p.name,c.name,tk.name,tl.name FROM yatish_timeslot t"
324  " INNER JOIN yatish_activity a ON t.activity_id = a.id"
325  " INNER JOIN yatish_project p ON a.project_id = p.id"
326  " INNER JOIN yatish_client c ON p.client_id = c.id"
327  " INNER JOIN yatish_task tk ON a.task_id = tk.id"
328  " INNER JOIN yatish_tool tl ON a.tool_id = tl.id"
329  " WHERE stop IS NOT NULL ORDER BY start;");
330  try {
331  wxDatabaseResultSet * results = masterDB->RunQueryWithResults (sql);
332  RawRecord record;
333  while ( results->Next() ) {
334  record.start = results->GetResultDate (1);
335  record.stop = results->GetResultDate (2);
336  record.project = results->GetResultString (3);
337  record.client = results->GetResultString (4);
338  record.task = results->GetResultString (5);
339  record.tool = results->GetResultString (6);
340  v.push_back (record);
341  }
342  masterDB->CloseResultSet (results);
343  }
344  CATCH (false)
345  return true;
346 }
347 
352 void yatishDBsqlite::AddToFilter (tableID tid, int choice) {
353  wxString sqlAnd;
354  switch (tid) {
355  case client_tid:
356  sqlAnd.Printf (" AND c.id = %ld", clientIDs[choice]);
357  break;
358  case project_tid:
359  sqlAnd.Printf (" AND p.id = %ld", projectIDs[choice]);
360  break;
361  case task_tid:
362  sqlAnd.Printf (" AND tk.id = %ld", taskIDs[choice]);
363  break;
364  case tool_tid:
365  sqlAnd.Printf (" AND tl.id = %ld", toolIDs[choice]);
366  break;
367  default:
368  return;
369  }
370  filter += sqlAnd;
371 }
372 
377 void yatishDBsqlite::AddToFilter (long activityID) {
378  wxString sqlAnd;
379  sqlAnd.Printf (" AND activity_id = %ld", activityID);
380  filter += sqlAnd;
381 }
382 
387 long yatishDBsqlite::FilteredTotal (wxTimeSpan& ts) const {
388  if (slotCount)
389  ts = totalSpan;
390  else
391  ts = wxTimeSpan::Hours (0);
392  return slotCount;
393 }
394 
401  if (!slotCount) return wxEmptyString;
402  double totalSeconds = totalSpan.GetSeconds().ToDouble();
403  double totalDays, averageHours;
404  totalDays = totalSeconds / 3600.; // hours still...
405  averageHours = totalDays / slotCount;
406  totalDays /= 7.; // ...nowadays!
407  return wxString::Format(_("SUM: %.1f days | AVG: %.1f hours (x%ld)"),
408  totalDays, averageHours, slotCount);
409 }
410 
415 void yatishDBsqlite::SetFirstDay (const wxDateTime& dt) {
416  firstDay = dt.ToUTC().FormatISOCombined();
417  wxFirstDay = dt; // stores a copy in case somebody needs it (yatishPDF...)
418 }
419 
424 void yatishDBsqlite::SetLastDay (const wxDateTime& dt) {
425  wxLastDay = dt; // stores a copy in case somebody needs it (yatishPDF...)
426  lastDay = ( dt + wxDateSpan::Day() ).ToUTC().FormatISOCombined();
427 }
428 
433 wxDateTime yatishDBsqlite::First () {
434  wxDateTime dt = wxDateTime::Now();
435  if (!masterDB) return dt;
436  wxString ans;
437  try {
438  wxString sql ("SELECT MIN(start) FROM ((((yatish_timeslot AS t"
439  " INNER JOIN yatish_activity AS a ON t.activity_id = a.id)"
440  " INNER JOIN yatish_project AS p ON a.project_id = p.id)"
441  " INNER JOIN yatish_client AS c ON p.client_id = c.id)"
442  " INNER JOIN yatish_task AS tk ON a.task_id = tk.id)"
443  " INNER JOIN yatish_tool AS tl ON a.tool_id = tl.id"
444  " WHERE t.sync <> 'D'");
445  sql += filter;
446  sql += ";";
447  ans = masterDB->GetSingleResultString (sql, 1);
448  }
449  CATCH (dt)
450  dt.ParseISOCombined (ans, ' ');
451  return dt.MakeFromUTC();
452 }
453 
458 wxDateTime yatishDBsqlite::Last () {
459  wxDateTime dt = wxDateTime::Now();
460  if (!masterDB) return dt;
461  wxString ans;
462  try {
463  wxString sql ("SELECT MAX(start) FROM ((((yatish_timeslot AS t"
464  " INNER JOIN yatish_activity AS a ON t.activity_id = a.id)"
465  " INNER JOIN yatish_project AS p ON a.project_id = p.id)"
466  " INNER JOIN yatish_client AS c ON p.client_id = c.id)"
467  " INNER JOIN yatish_task AS tk ON a.task_id = tk.id)"
468  " INNER JOIN yatish_tool AS tl ON a.tool_id = tl.id"
469  " WHERE t.sync <> 'D'");
470  sql += filter;
471  sql += ";";
472  ans = masterDB->GetSingleResultString (sql, 1);
473  }
474  CATCH (dt)
475  dt.ParseISOCombined (ans, ' ');
476  return dt.MakeFromUTC();
477 }
478 
483  long id = wxNOT_FOUND;
484  if (!masterDB) return id;
485  try {
486  wxString sql ("SELECT activity_id FROM yatish_timeslot ORDER BY start DESC LIMIT 1;");
487  wxDatabaseResultSet * results = masterDB->RunQueryWithResults (sql);
488  if ( results->Next() ) id = results->GetResultLong (1);
489  masterDB->CloseResultSet (results);
490  }
491  CATCH (id)
492  return id;
493 }
494 
499 long yatishDBsqlite::Activity (long id) {
500  long rid = wxNOT_FOUND;
501  if (!masterDB) return rid;
502  try {
503  wxString sql = wxString::Format("SELECT activity_id FROM yatish_timeslot WHERE id=%ld;", id);
504  rid = masterDB->GetSingleResultLong (sql, 1);
505  }
506  CATCH (rid)
507  return rid;
508 }
509 
516 bool yatishDBsqlite::Delete (tableID tid, long id) {
517  if (!masterDB) return false;
518  if ( tid != timeslot_tid &&
519  wxMessageBox ( _("Owing to foreign key constraints\nin the Yatish database,"
520  "\nrecords refering to this item\nwill also be deleted."),
521  _("Confirm deletion"),
522  wxICON_EXCLAMATION|wxOK|wxCANCEL|wxCANCEL_DEFAULT )
523  == wxCANCEL ) return false;
524  wxString sql, status;
525  try {
526  sql.Printf ("SELECT sync FROM yatish_%s WHERE id = %ld;", tableName[tid], id);
527  status = masterDB->GetSingleResultString(sql, 1);
528  }
529  CATCH (false)
530  if (status == 'I')
531  sql.Printf ("DELETE FROM yatish_%s WHERE id = %ld;", tableName[tid], id);
532  else
533  sql.Printf ("UPDATE yatish_%s SET sync='D' WHERE id = %ld;", tableName[tid], id);
534  try {
535  masterDB->RunQuery (sql);
536  }
537  CATCH (false)
538  return true;
539 }
540 
546 wxString yatishDBsqlite::ReadName (tableID tid, long id) {
547  if (!masterDB) return "";
548  try {
549  wxString sql;
550  sql.Printf ("SELECT name FROM yatish_%s WHERE id = %ld;", tableName[tid], id);
551  return masterDB->GetSingleResultString (sql, 1);
552  }
553  CATCH ("")
554 }
555 
562 bool yatishDBsqlite::ReadDates (long id, wxDateTime& dt1, wxDateTime& dt2) {
563  if (!masterDB) return false;
564  try {
565  wxString sql;
566  sql.Printf ("SELECT start,stop FROM yatish_timeslot WHERE id = %ld;", id);
567  wxDatabaseResultSet * results = masterDB->RunQueryWithResults (sql);
568  if ( !results->Next() ) {
569  masterDB->CloseResultSet (results);
570  return false;
571  }
572  dt1 = results->GetResultDate (1); dt2 = results->GetResultDate (2);
573  masterDB->CloseResultSet (results);
574  }
575  CATCH (false)
576  dt1.MakeFromUTC();
577  if ( !dt2.IsValid() ) return false;
578  dt2.MakeFromUTC();
579  return true;
580 }
581 
588 bool yatishDBsqlite::RecordName (tableID tid, long id, const wxString& str) {
589  if (!masterDB) return false;
590  if (tid == project_tid || tid == activity_tid || tid == timeslot_tid) return false;
591  try {
592  wxString sql, tbl = tableName[tid], sync;
593  if (id == wxNOT_FOUND)
594  sql.Printf ("INSERT INTO yatish_%s (name,sync) VALUES ('%s','I');", tbl, str);
595  else {
596  sql.Printf ("SELECT sync FROM yatish_%s WHERE id = %ld", tbl, id);
597  sync = masterDB->GetSingleResultString (sql, 1);
598  if (sync == 'I') // don't switch to 'U' state before it is synchronized
599  sql.Printf ("UPDATE yatish_%s SET name='%s'"
600  " WHERE id = %ld;", tbl, str, id);
601  else
602  sql.Printf ("UPDATE yatish_%s SET name='%s',sync='U'"
603  "WHERE id = %ld;", tbl, str, id);
604  }
605  masterDB->RunQuery (sql);
606  }
607  CATCH (false)
608  return true;
609 }
610 
617 bool yatishDBsqlite::RecordProject (long id, const wxString& str, int client_choice) {
618  if (!masterDB) return false;
619  try {
620  wxString sql, sync;
621  int clientID = clientIDs[client_choice];
622  if (id == wxNOT_FOUND)
623  sql.Printf ("INSERT INTO yatish_project (name,client_id,sync) VALUES ('%s',%d,'I');",
624  str, clientID);
625  else {
626  sql.Printf ("SELECT sync FROM yatish_project WHERE id = %ld", id);
627  sync = masterDB->GetSingleResultString (sql, 1);
628  if (sync == 'I') // don't switch to 'U' state before it is synchronized
629  sql.Printf ("UPDATE yatish_project SET name='%s',client_id=%d"
630  " WHERE id = %ld;", str, clientID, id);
631  else
632  sql.Printf ("UPDATE yatish_project SET name='%s',client_id=%d,sync='U'"
633  " WHERE id = %ld;", str, clientID, id);
634  }
635  masterDB->RunQuery (sql);
636  }
637  CATCH (false)
638  return true;
639 }
640 
646 bool yatishDBsqlite::RecordActivity (long id, int project, int task, int tool) {
647  if (!masterDB) return false;
648  try {
649  wxString sql, sync;
650  int projectID = projectIDs[project],
651  taskID = taskIDs[task],
652  toolID = toolIDs[tool];
653  if (id == wxNOT_FOUND)
654  sql.Printf ("INSERT INTO yatish_activity (project_id,task_id,tool_id,sync)"
655  " VALUES (%d,%d,%d,'I');", projectID, taskID, toolID);
656  else {
657  sql.Printf ("SELECT sync FROM yatish_activity WHERE id = %ld", id);
658  sync = masterDB->GetSingleResultString (sql, 1);
659  if (sync == 'I') // don't switch to 'U' state before it is synchronized
660  sql.Printf ("UPDATE yatish_activity SET project_id=%d,task_id=%d,tool_id=%d"
661  " WHERE id = %ld;", projectID, taskID, toolID, id);
662  else
663  sql.Printf ("UPDATE yatish_activity SET project_id=%d,task_id=%d,tool_id=%d,sync='U'"
664  " WHERE id = %ld;", projectID, taskID, toolID, id);
665  }
666  masterDB->RunQuery (sql);
667  }
668  CATCH (false)
669  return true;
670 }
671 
681  const wxDateTime& dt1, const wxDateTime& dt2,
682  int project, int task, int tool) {
683  if (!masterDB) return false;
684  wxString start = dt1.ToUTC().FormatISOCombined(' ');
685  wxString stop = dt2.ToUTC().FormatISOCombined(' ');
686  int projectID = projectIDs[project],
687  taskID = taskIDs[task],
688  toolID = toolIDs[tool];
689  wxString sql, sync;
690  sql.Printf ("SELECT id FROM yatish_activity"
691  " WHERE project_id = %d AND task_id = %d AND tool_id = %d;",
692  projectID, taskID, toolID);
693  try {
694  wxDatabaseResultSet * results = masterDB->RunQueryWithResults (sql);
695  if ( !results->Next() ) {
696  wxString sql2;
697  sql2.Printf ("INSERT INTO yatish_activity (project_id,task_id,tool_id,sync)"
698  " VALUES (%d,%d,%d,'I');",
699  projectID, taskID, toolID);
700  masterDB->CloseResultSet (results);
701  masterDB->RunQuery (sql2);
702  results = masterDB->RunQueryWithResults (sql);
703  results->Next();
704  }
705  long activityID = results->GetResultLong (1);
706  masterDB->CloseResultSet (results);
707  if (id == wxNOT_FOUND)
708  sql.Printf ("INSERT INTO yatish_timeslot (start,stop,activity_id,sync)"
709  " VALUES ('%s','%s',%ld,'I');", start, stop, activityID);
710  else {
711  sql.Printf ("SELECT sync FROM yatish_timeslot WHERE id = %ld", id);
712  sync = masterDB->GetSingleResultString (sql, 1);
713  if (sync == 'I') // don't switch to 'U' state before it is synchronized
714  sql.Printf ("UPDATE yatish_timeslot SET start='%s',stop='%s',activity_id=%ld"
715  " WHERE id = %ld;", start, stop, activityID, id);
716  else
717  sql.Printf ("UPDATE yatish_timeslot SET start='%s',stop='%s',activity_id=%ld,sync='U'"
718  " WHERE id = %ld;", start, stop, activityID, id);
719  }
720  masterDB->RunQuery (sql);
721  }
722  CATCH (false)
723  return true;
724 }
static wxDatabase * masterDB
Definition: yatishDB.h:46
bool TablesOk(wxDatabase *)
Returns false if any of the yatish table is missings.
Definition: yatishDB.cpp:83
static const char * tableName[]
Must be defined in the same order as enum tableID.
Definition: yatishDB.h:44
wxDatabase * GetDatabase(const wxString &)
Sets up a (configuration) flux using its argument then calls wxDatabase::GetDatabase().
Definition: yatishDB.cpp:48
bool ReadDates(long, wxDateTime &, wxDateTime &)
Reads the start and stop fields of a yatish_timeslot record.
wxDateTime wxFirstDay
bool FillChoice(wxChoice *, tableID)
Fills a wxChoice.
wxArrayLong toolIDs
bool RecordActivity(long, int, int, int)
Modifies or creates a record in the yatish_activity table.
void SetFirstDay(const wxDateTime &)
Sets private member firstDay (for future SQL queries).
wxDateTime wxLastDay
bool RecordTimeslot(long, const wxDateTime &, const wxDateTime &, int, int, int)
Modifies or creates a record in the yatish_timeslot table.
bool FillList(wxListCtrl *, tableID)
Fills a wxListCtrl.
long FilteredTotal(wxTimeSpan &) const
Returns the total duration of currently viewed timeslots (and their count).
bool FillPlotData(RawData &)
Fills a RawData (typedefined in yatishTypes.h).
wxArrayLong clientIDs
wxString firstDay
bool RecordName(tableID, long, const wxString &)
Modifies or creates a record with only one field (called name).
wxString FilteredTotalFormatted()
Writes the total and average durations of currently viewed timeslots.
yatishDBsqlite()
Mainly connects to the yatish.sqlite database.
wxString ReadName(tableID, long)
Reads a wxString from the name column.
wxDateTime Last()
Obtains the maximum time in column start from currently selected rows of table yatish_timeslot.
wxTimeSpan totalSpan
int RunningTimeslots()
Determines the number n of unfinished timeslots.
wxDateTime First()
Obtains the minimum time in column start from currently selected rows of table yatish_timeslot.
wxArrayLong projectIDs
wxArrayLong taskIDs
void SetLastDay(const wxDateTime &)
Sets private member lastDay (for future SQL queries).
bool Delete(tableID, long)
Marks a local record for deletion.
void AddToFilter(tableID, int)
Adds a condition to the WHERE clause of FillList().
bool RecordProject(long, const wxString &, int)
Modifies or creates a record in the yatish_project table.
bool StartTimeslot(int, int, int)
Starts a new row in the timeslot table.
int ChoiceSelector(tableID, long)
Finds the proper index for selection in a wxChoice.
long Activity(long)
Reads the activity_id in a record of yatish_timeslot.
wxString lastDay
bool StopTimeslot()
Stops current timeslot.
long LastActivity()
Reads the last activity_id in yatish_timeslot.
Element of typefined std:vector RawData (yatishPlot.big_data).
Definition: yatishTypes.h:21
wxString tool
Definition: yatishTypes.h:23
wxString project
Definition: yatishTypes.h:23
wxDateTime start
Definition: yatishTypes.h:22
wxString task
Definition: yatishTypes.h:23
wxString client
Definition: yatishTypes.h:23
wxDateTime stop
Definition: yatishTypes.h:22
#define CATCH(returnValue)
Definition: yatishDB.h:22
tableID
Definition: yatishDB.h:13
@ tool_tid
Definition: yatishDB.h:16
@ task_tid
Definition: yatishDB.h:15
@ timeslot_tid
Definition: yatishDB.h:19
@ client_tid
Definition: yatishDB.h:14
@ project_tid
Definition: yatishDB.h:17
@ activity_tid
Definition: yatishDB.h:18
vector< RawRecord > RawData
Definition: yatishTypes.h:25