1 // CalendarDataStorage.cpp - CalendarDataStorage class
3 // (c) 2016-2017 Xestia Software Development.
5 // This file is part of Xestia Calendar.
7 // Xestia Calendar is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
11 // Xestia Calendar is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Calendar. If not, see <http://www.gnu.org/licenses/>
19 #include "CalendarDataStorage.h"
21 #define CDS_RANDOMPOW 24
27 static int callback(void *NotUsed, int argc, char **argv, char **azColName){
31 CalendarDataStorage::CalendarDataStorage(){
33 // Initialise the SQLite database.
35 sqlite3_open_v2(":memory:", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_FULLMUTEX, nullptr);
40 CalendarDataStorage::~CalendarDataStorage(){
42 // Destory the SQLite database.
48 void CalendarDataStorage::SetupTables(){
50 // Setup the tables for the Calendar Data Storage.
52 char *setupTablesErrMsg = nullptr;
55 // Setup the accounts table.
57 const char *accountsTableString;
58 accountsTableString = "CREATE TABLE accounts(id INTEGER PRIMARY KEY AUTOINCREMENT"
59 ", preferencesid INTEGER"
63 resultCode = sqlite3_exec(db, accountsTableString, callback, nullptr, &setupTablesErrMsg);
66 DataStorageInitOK = false;
70 // Setup the calendars table.
72 const char *calendarTableString;
73 calendarTableString = "CREATE TABLE calendars(id INTEGER PRIMARY KEY AUTOINCREMENT"
81 resultCode = sqlite3_exec(db, calendarTableString, callback, nullptr, &setupTablesErrMsg);
84 DataStorageInitOK = false;
88 // Setup the calendar entries table.
90 const char *calendarentriesTableString;
91 calendarentriesTableString = "CREATE TABLE calendarentries(id INTEGER PRIMARY KEY AUTOINCREMENT"
92 ", calendarid INTEGER"
94 ", entrydescription TEXT"
95 ", entrystartyear INTEGER"
96 ", entrystartmonth INTEGER"
97 ", entrystartday INTEGER"
98 ", entrystarthour INTEGER"
99 ", entrystartminute INTEGER"
100 ", entrystartsecond INTEGER"
101 ", entryendyear INTEGER"
102 ", entryendmonth INTEGER"
103 ", entryendday INTEGER"
104 ", entryendhour INTEGER"
105 ", entryendminute INTEGER"
106 ", entryendsecond INTEGER"
107 ", entrydurationweek INTEGER"
108 ", entrydurationday INTEGER"
109 ", entrydurationhour INTEGER"
110 ", entrydurationminute INTEGER"
111 ", entrydurationsecond INTEGER"
115 resultCode = sqlite3_exec(db, calendarentriesTableString, callback, nullptr, &setupTablesErrMsg);
117 if (resultCode != 0){
118 DataStorageInitOK = false;
122 // Setup the checksums table.
124 const char *checksumsTableString;
125 checksumsTableString = "CREATE TABLE checksums(checksumname TEXT PRIMARY KEY "
126 ", checksumvalue TEXT);";
128 resultCode = sqlite3_exec(db, checksumsTableString, callback, nullptr, &setupTablesErrMsg);
130 if (resultCode != 0){
131 DataStorageInitOK = false;
135 // Setup internal checksums.
137 CDSChecksumResult addChecksum = AddChecksum("internal_updatedata", "");
139 if (addChecksum != CDSCHECKSUM_OK){
140 DataStorageInitOK = false;
144 DataStorageInitOK = true;
148 bool CalendarDataStorage::DidInitOK()
151 return DataStorageInitOK;
155 CDSAccountResult CalendarDataStorage::AddAccount(string accountName, int accountPreferencesID)
158 CDSAccountResult addResult = CDSACCOUNT_UNITTESTFAIL;
161 sqlite3_stmt *statementHandle;
163 resultCode = sqlite3_prepare_v2(db, "INSERT INTO accounts (name, preferencesid) VALUES(?1, ?2);", -1, &statementHandle, nullptr);
165 if (resultCode != 0){
166 return CDSACCOUNT_FAILED;
169 resultCode = sqlite3_bind_text(statementHandle, 1, accountName.c_str(), -1, SQLITE_STATIC);
171 if (resultCode != 0){
172 return CDSACCOUNT_FAILED;
175 resultCode = sqlite3_bind_int(statementHandle, 2, accountPreferencesID);
177 if (resultCode != 0){
178 return CDSACCOUNT_FAILED;
181 resultCode = sqlite3_step(statementHandle);
183 if (resultCode != SQLITE_DONE){
184 return CDSACCOUNT_FAILED;
187 // Update the checksum.
189 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
191 addResult = CDSACCOUNT_OK;
197 CDSAccountList CalendarDataStorage::GetAccountList()
200 CDSAccountList accountList;
202 // Check if calendar exists first.
206 sqlite3_stmt *statementHandle;
208 resultCode = sqlite3_prepare_v2(db, "SELECT id, name, preferencesid from accounts;", -1, &statementHandle, nullptr);
210 if (resultCode != 0){
211 accountList.getAccountListResult = CDSACCOUNT_FAILED;
215 if (resultCode != 0){
216 accountList.getAccountListResult = CDSACCOUNT_FAILED;
220 resultCode = sqlite3_step(statementHandle);
222 if (resultCode == SQLITE_ROW){
224 } else if (resultCode == SQLITE_DONE) {
225 accountList.getAccountListResult = CDSACCOUNT_NOACCOUNT;
228 accountList.getAccountListResult = CDSACCOUNT_FAILED;
232 while (resultCode == SQLITE_ROW){
234 CDSGetAccountInfo accountInfo;
236 accountInfo.accountID = sqlite3_column_int(statementHandle, 0);
237 accountInfo.accountPreferencesID = sqlite3_column_int(statementHandle, 2);
239 stringstream calendarStream;
241 calendarStream << sqlite3_column_text(statementHandle, 1);
243 accountInfo.accountName = calendarStream.str();
244 accountInfo.accountInfoResult = CDSACCOUNT_OK;
246 accountList.accountList.push_back(accountInfo);
248 resultCode = sqlite3_step(statementHandle);
252 accountList.getAccountListResult = CDSACCOUNT_OK;
258 CDSGetAccountInfo CalendarDataStorage::GetAccount(string accountName)
261 CDSGetAccountInfo accountInfo;
262 accountInfo.accountInfoResult = CDSACCOUNT_UNITTESTFAIL;
265 sqlite3_stmt *statementHandle;
267 resultCode = sqlite3_prepare_v2(db, "SELECT name, id, preferencesid FROM accounts WHERE name=(?1);", -1, &statementHandle, nullptr);
269 if (resultCode != 0){
270 accountInfo.accountInfoResult = CDSACCOUNT_FAILED;
274 resultCode = sqlite3_bind_text(statementHandle, 1, accountName.c_str(), -1, SQLITE_STATIC);
276 if (resultCode != 0){
277 accountInfo.accountInfoResult = CDSACCOUNT_FAILED;
281 resultCode = sqlite3_step(statementHandle);
283 if (resultCode == SQLITE_DONE){
285 accountInfo.accountInfoResult = CDSACCOUNT_NOACCOUNT;
288 } else if (resultCode == SQLITE_ROW){
290 // Get the result data.
292 stringstream accountNameStream;
294 accountNameStream << sqlite3_column_text(statementHandle, 0);
296 accountInfo.accountName = accountNameStream.str();
297 accountInfo.accountID = sqlite3_column_int(statementHandle, 1);
298 accountInfo.accountPreferencesID = sqlite3_column_int(statementHandle, 2);
300 accountInfo.accountInfoResult = CDSACCOUNT_OK;
305 accountInfo.accountInfoResult = CDSACCOUNT_FAILED;
314 CDSAccountResult CalendarDataStorage::UpdateAccount(int accountID, string accountName)
317 CDSAccountResult updateResult = CDSACCOUNT_UNITTESTFAIL;
320 sqlite3_stmt *findHandle;
321 sqlite3_stmt *statementHandle;
323 // Check if account exists first.
325 resultCode = sqlite3_prepare_v2(db, "SELECT id from accounts WHERE id=(?1);", -1, &findHandle, nullptr);
327 if (resultCode != 0){
328 return CDSACCOUNT_FAILED;
331 resultCode = sqlite3_bind_int(findHandle, 1, accountID);
333 if (resultCode != 0){
334 return CDSACCOUNT_FAILED;
337 resultCode = sqlite3_step(findHandle);
339 if (resultCode == SQLITE_ROW){
341 } else if (resultCode == SQLITE_DONE) {
342 return CDSACCOUNT_NOACCOUNT;
344 return CDSACCOUNT_FAILED;
347 // Update the account.
349 resultCode = sqlite3_prepare_v2(db, "UPDATE accounts SET name=(?1) WHERE id=(?2);", -1, &statementHandle, nullptr);
351 if (resultCode != 0){
352 return CDSACCOUNT_FAILED;
355 resultCode = sqlite3_bind_text(statementHandle, 1, accountName.c_str(), -1, SQLITE_STATIC);
357 if (resultCode != 0){
358 return CDSACCOUNT_FAILED;
361 resultCode = sqlite3_bind_int(statementHandle, 2, accountID);
363 if (resultCode != 0){
364 return CDSACCOUNT_FAILED;
367 resultCode = sqlite3_step(statementHandle);
369 if (resultCode != SQLITE_DONE){
370 return CDSACCOUNT_FAILED;
373 // Update the checksum.
375 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
377 updateResult = CDSACCOUNT_OK;
383 CDSAccountResult CalendarDataStorage::DeleteAccount(int accountID)
386 CDSAccountResult deleteResult = CDSACCOUNT_UNITTESTFAIL;
388 // Check if account exists first.
390 sqlite3_stmt *findHandle;
391 sqlite3_stmt *statementHandle;
392 sqlite3_stmt *calendarHandle;
395 resultCode = sqlite3_prepare_v2(db, "SELECT id from accounts WHERE id=(?1);", -1, &findHandle, nullptr);
397 if (resultCode != 0){
398 return CDSACCOUNT_FAILED;
401 resultCode = sqlite3_bind_int(findHandle, 1, accountID);
403 if (resultCode != 0){
404 return CDSACCOUNT_FAILED;
407 resultCode = sqlite3_step(findHandle);
409 if (resultCode == SQLITE_ROW){
411 } else if (resultCode == SQLITE_DONE) {
412 return CDSACCOUNT_NOACCOUNT;
414 return CDSACCOUNT_FAILED;
417 // Delete the account.
419 resultCode = sqlite3_prepare_v2(db, "DELETE FROM accounts WHERE id=(?1);", -1, &statementHandle, nullptr);
421 if (resultCode != 0){
422 return CDSACCOUNT_FAILED;
425 resultCode = sqlite3_bind_int(statementHandle, 1, accountID);
427 if (resultCode != 0){
428 return CDSACCOUNT_FAILED;
431 resultCode = sqlite3_step(statementHandle);
433 if (resultCode == SQLITE_DONE){
434 //deleteResult = CDSACCOUNT_OK;
436 return CDSACCOUNT_FAILED;
439 // Get the calendar IDs and delete each calendar (and associated entries).
441 resultCode = sqlite3_prepare_v2(db, "SELECT id FROM calendars WHERE accountid=(?1);", -1, &calendarHandle, nullptr);
443 if (resultCode != 0){
444 return CDSACCOUNT_FAILED;
447 resultCode = sqlite3_bind_int(calendarHandle, 1, accountID);
449 if (resultCode != 0){
450 return CDSACCOUNT_FAILED;
453 resultCode = sqlite3_step(calendarHandle);
455 if (resultCode == SQLITE_DONE || resultCode == SQLITE_ROW){
456 deleteResult = CDSACCOUNT_OK;
458 return CDSACCOUNT_FAILED;
461 while (resultCode == SQLITE_ROW){
463 int calendarDeleteID = sqlite3_column_int(calendarHandle, 0);
465 DeleteCalendar(calendarDeleteID);
467 resultCode = sqlite3_step(calendarHandle);
471 // Update the checksum.
473 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
475 deleteResult = CDSACCOUNT_OK;
482 CDSCalendarResult CalendarDataStorage::AddCalendar(int accountID, string calendarName, string calendarID, Colour calendarColour, string calendarDescription)
485 CDSCalendarResult addResult = CDSCALENDAR_UNITTESTFAIL;
488 sqlite3_stmt *statementHandle;
490 resultCode = sqlite3_prepare_v2(db, "INSERT INTO calendars (name, calendarid, accountid, colour, description) VALUES(?1, ?2, ?3, ?4, ?5);", -1, &statementHandle, nullptr);
492 if (resultCode != 0){
493 return CDSCALENDAR_FAILED;
496 resultCode = sqlite3_bind_text(statementHandle, 1, calendarName.c_str(), -1, SQLITE_STATIC);
498 if (resultCode != 0){
499 return CDSCALENDAR_FAILED;
502 resultCode = sqlite3_bind_text(statementHandle, 2, calendarID.c_str(), -1, SQLITE_STATIC);
504 if (resultCode != 0){
505 return CDSCALENDAR_FAILED;
508 resultCode = sqlite3_bind_int(statementHandle, 3, accountID);
510 if (resultCode != 0){
511 return CDSCALENDAR_FAILED;
514 resultCode = sqlite3_bind_text(statementHandle, 4, ((string)calendarColour).c_str(), -1, SQLITE_STATIC);
516 if (resultCode != 0){
517 return CDSCALENDAR_FAILED;
520 resultCode = sqlite3_bind_text(statementHandle, 5, calendarDescription.c_str(), -1, SQLITE_STATIC);
522 if (resultCode != 0){
523 return CDSCALENDAR_FAILED;
526 resultCode = sqlite3_step(statementHandle);
528 if (resultCode != SQLITE_DONE){
529 return CDSCALENDAR_FAILED;
532 // Update the checksum.
534 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
536 addResult = CDSCALENDAR_OK;
542 CDSGetCalendarInfo CalendarDataStorage::GetCalendar(std::string accountName, std::string calendarTextID)
545 CDSGetAccountInfo accountResult;
546 CDSGetCalendarInfo calendarResult;
547 sqlite3_stmt *statementHandle;
550 // Check if the account exists.
552 accountResult = GetAccount(accountName);
554 switch (accountResult.accountInfoResult){
557 calendarResult.accountName = accountResult.accountName;
558 calendarResult.accountInfoResult = CDSACCOUNT_OK;
560 case CDSACCOUNT_FAILED:
561 calendarResult.accountInfoResult = CDSACCOUNT_FAILED;
562 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
563 return calendarResult;
564 case CDSACCOUNT_NOACCOUNT:
565 calendarResult.accountInfoResult = CDSACCOUNT_NOACCOUNT;
566 calendarResult.calendarInfoResult = CDSCALENDAR_NOCALENDAR;
567 return calendarResult;
571 // Check if the calendar exists.
573 resultCode = sqlite3_prepare_v2(db, "SELECT id, accountid, name, calendarid, colour, description FROM calendars WHERE accountid=(?1) AND calendarid=(?2);", -1, &statementHandle, nullptr);
575 if (resultCode != 0){
576 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
577 return calendarResult;
580 resultCode = sqlite3_bind_int(statementHandle, 1, accountResult.accountID);
582 if (resultCode != 0){
583 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
584 return calendarResult;
587 resultCode = sqlite3_bind_text(statementHandle, 2, calendarTextID.c_str(), -1, SQLITE_STATIC);
589 if (resultCode != 0){
590 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
591 return calendarResult;
594 resultCode = sqlite3_step(statementHandle);
596 if (resultCode == SQLITE_DONE){
598 calendarResult.calendarInfoResult = CDSCALENDAR_NOCALENDAR;
599 return calendarResult;
601 } else if (resultCode == SQLITE_ROW){
603 // Get the calendar name.
605 stringstream calendarStream;
607 calendarStream << sqlite3_column_text(statementHandle, 2);
608 calendarResult.calendarName = calendarStream.str();
610 calendarStream.str("");
611 calendarStream << sqlite3_column_text(statementHandle, 3);
612 calendarResult.calendarTextID = calendarStream.str();
614 calendarStream.str("");
615 calendarStream << sqlite3_column_text(statementHandle, 4);
616 calendarResult.calendarColour = calendarStream.str();
618 calendarStream.str("");
619 calendarStream << sqlite3_column_text(statementHandle, 5);
620 calendarResult.calendarDescription = calendarStream.str();
622 calendarResult.calendarID = sqlite3_column_int(statementHandle, 0);
623 calendarResult.accountID = sqlite3_column_int(statementHandle, 1);
624 calendarResult.calendarInfoResult = CDSCALENDAR_OK;
625 return calendarResult;
629 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
630 return calendarResult;
634 return calendarResult;
638 CDSGetCalendarInfo CalendarDataStorage::GetCalendar(int calendarID)
641 CDSGetCalendarInfo calendarResult;
642 sqlite3_stmt *statementHandle;
643 sqlite3_stmt *accountHandle;
646 // Check if the calendar exists.
648 resultCode = sqlite3_prepare_v2(db, "SELECT id, accountid, name, calendarid, colour, description FROM calendars WHERE id=(?1);", -1, &statementHandle, nullptr);
650 if (resultCode != 0){
651 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
652 return calendarResult;
655 resultCode = sqlite3_bind_int(statementHandle, 1, calendarID);
657 if (resultCode != 0){
658 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
659 return calendarResult;
662 resultCode = sqlite3_step(statementHandle);
664 if (resultCode == SQLITE_DONE){
666 calendarResult.calendarInfoResult = CDSCALENDAR_NOCALENDAR;
667 return calendarResult;
669 } else if (resultCode == SQLITE_ROW){
671 // Get the calendar data.
673 stringstream calendarStream;
675 calendarStream << sqlite3_column_text(statementHandle, 2);
676 calendarResult.calendarName = calendarStream.str();
678 calendarStream.str("");
679 calendarStream << sqlite3_column_text(statementHandle, 3);
680 calendarResult.calendarTextID = calendarStream.str();
682 calendarStream.str("");
683 calendarStream << sqlite3_column_text(statementHandle, 4);
684 calendarResult.calendarColour = calendarStream.str();
686 calendarStream.str("");
687 calendarStream << sqlite3_column_text(statementHandle, 5);
688 calendarResult.calendarDescription = calendarStream.str();
690 calendarResult.calendarID = sqlite3_column_int(statementHandle, 0);
691 calendarResult.accountID = sqlite3_column_int(statementHandle, 1);
693 // Get the account name.
695 resultCode = sqlite3_prepare_v2(db, "SELECT name FROM accounts WHERE id=(?1);", -1, &accountHandle, nullptr);
697 if (resultCode != 0){
698 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
699 return calendarResult;
702 resultCode = sqlite3_bind_int(accountHandle, 1, calendarResult.accountID);
704 if (resultCode != 0){
705 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
706 return calendarResult;
709 resultCode = sqlite3_step(accountHandle);
711 if (resultCode == SQLITE_ROW){
713 stringstream accountStream;
714 accountStream << sqlite3_column_text(accountHandle, 0);
715 calendarResult.accountName = accountStream.str();
716 calendarResult.accountInfoResult = CDSACCOUNT_OK;
720 calendarResult.accountInfoResult = CDSACCOUNT_FAILED;
724 calendarResult.calendarInfoResult = CDSCALENDAR_OK;
725 return calendarResult;
729 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
730 return calendarResult;
734 return calendarResult;
739 CDSCalendarResult CalendarDataStorage::UpdateCalendar(int calendarID, string calendarName, Colour calendarColour, std::string calendarDescription)
742 CDSCalendarResult updateResult = CDSCALENDAR_UNITTESTFAIL;
745 sqlite3_stmt *findHandle;
746 sqlite3_stmt *statementHandle;
748 // Check if calendar exists first.
750 resultCode = sqlite3_prepare_v2(db, "SELECT id from calendars WHERE id=(?1);", -1, &findHandle, nullptr);
752 if (resultCode != 0){
753 return CDSCALENDAR_FAILED;
756 resultCode = sqlite3_bind_int(findHandle, 1, calendarID);
758 if (resultCode != 0){
759 return CDSCALENDAR_FAILED;
762 resultCode = sqlite3_step(findHandle);
764 if (resultCode == SQLITE_ROW){
766 } else if (resultCode == SQLITE_DONE) {
767 return CDSCALENDAR_NOCALENDAR;
769 return CDSCALENDAR_FAILED;
772 // Update the account.
774 resultCode = sqlite3_prepare_v2(db, "UPDATE calendars SET name=(?1), colour=(?2), description=(?3) WHERE id=(?4);", -1, &statementHandle, nullptr);
776 if (resultCode != 0){
777 return CDSCALENDAR_FAILED;
780 resultCode = sqlite3_bind_text(statementHandle, 1, calendarName.c_str(), -1, SQLITE_STATIC);
782 if (resultCode != 0){
783 return CDSCALENDAR_FAILED;
786 resultCode = sqlite3_bind_text(statementHandle, 2, string(calendarColour).c_str(), -1, SQLITE_STATIC);
788 if (resultCode != 0){
789 return CDSCALENDAR_FAILED;
792 resultCode = sqlite3_bind_text(statementHandle, 3, calendarDescription.c_str(), -1, SQLITE_STATIC);
794 if (resultCode != 0){
795 return CDSCALENDAR_FAILED;
798 resultCode = sqlite3_bind_int(statementHandle, 4, calendarID);
800 if (resultCode != 0){
801 return CDSCALENDAR_FAILED;
804 resultCode = sqlite3_step(statementHandle);
806 if (resultCode != SQLITE_DONE){
807 return CDSCALENDAR_FAILED;
810 // Update the checksum.
812 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
814 updateResult = CDSCALENDAR_OK;
820 CDSCalendarResult CalendarDataStorage::DeleteCalendar(int calendarID)
823 CDSCalendarResult deleteResult = CDSCALENDAR_UNITTESTFAIL;
825 // Check if account exists first.
827 sqlite3_stmt *findHandle;
828 sqlite3_stmt *statementHandle;
829 sqlite3_stmt *entriesHandle;
832 resultCode = sqlite3_prepare_v2(db, "SELECT id from calendars WHERE id=(?1);", -1, &findHandle, nullptr);
834 if (resultCode != 0){
835 return CDSCALENDAR_FAILED;
838 resultCode = sqlite3_bind_int(findHandle, 1, calendarID);
840 if (resultCode != 0){
841 return CDSCALENDAR_FAILED;
844 resultCode = sqlite3_step(findHandle);
846 if (resultCode == SQLITE_ROW){
848 } else if (resultCode == SQLITE_DONE) {
849 return CDSCALENDAR_NOCALENDAR;
851 return CDSCALENDAR_FAILED;
854 // Delete the calendar.
856 resultCode = sqlite3_prepare_v2(db, "DELETE FROM calendars WHERE id=(?1);", -1, &statementHandle, nullptr);
858 if (resultCode != 0){
859 return CDSCALENDAR_FAILED;
862 resultCode = sqlite3_bind_int(statementHandle, 1, calendarID);
864 if (resultCode != 0){
865 return CDSCALENDAR_FAILED;
868 resultCode = sqlite3_step(statementHandle);
870 if (resultCode != SQLITE_DONE){
871 return CDSCALENDAR_FAILED;
874 // Delete the calendar entries.
876 resultCode = sqlite3_prepare_v2(db, "DELETE FROM calendarentries WHERE calendarid=(?1);", -1, &entriesHandle, nullptr);
878 if (resultCode != 0){
879 return CDSCALENDAR_FAILED;
882 resultCode = sqlite3_bind_int(entriesHandle, 1, calendarID);
884 if (resultCode != 0){
885 return CDSCALENDAR_FAILED;
888 resultCode = sqlite3_step(entriesHandle);
890 if (resultCode == SQLITE_DONE){
891 deleteResult = CDSCALENDAR_OK;
893 return CDSCALENDAR_FAILED;
896 // Update the checksum.
898 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
904 CDSAddEntryResult CalendarDataStorage::AddEvent(int calendarID, std::string filename)
907 CDSAddEntryResult addResult;
908 addResult.addEventResult = CDSENTRY_UNITTESTFAIL;
910 // Load the event file.
912 CalendarEventObject eventData;
913 CalendarObjectLoadResult eventLoadResult = eventData.LoadFile(filename);
915 // Check the result of the event file load.
917 switch (eventLoadResult){
919 case CALENDAROBJECTLOAD_OK:
921 case CALENDAROBJECTLOAD_MISSING:
922 addResult.addEventResult = CDSENTRY_MISSINGFILE;
924 case CALENDAROBJECTLOAD_INVALIDFORMAT:
925 addResult.addEventResult = CDSENTRY_INVALIDFILE;
927 case CALENDAROBJECTLOAD_CANNOTOPEN:
928 addResult.addEventResult = CDSENTRY_CANNOTOPENFILE;
933 // Check if calendar exists first.
937 sqlite3_stmt *findHandle;
938 sqlite3_stmt *statementHandle;
940 resultCode = sqlite3_prepare_v2(db, "SELECT id from calendars WHERE id=(?1);", -1, &findHandle, nullptr);
942 if (resultCode != 0){
943 addResult.addEventResult = CDSENTRY_FAILED;
947 resultCode = sqlite3_bind_int(findHandle, 1, calendarID);
949 if (resultCode != 0){
950 addResult.addEventResult = CDSENTRY_FAILED;
954 resultCode = sqlite3_step(findHandle);
956 if (resultCode == SQLITE_ROW){
958 } else if (resultCode == SQLITE_DONE) {
959 addResult.addEventResult = CDSENTRY_NOCALENDAR;
962 addResult.addEventResult = CDSENTRY_FAILED;
966 // Get the required values from the event object.
968 int eventStartYear = 0;
969 int eventStartMonth = 0;
970 int eventStartDay = 0;
971 int eventStartHour = 0;
972 int eventStartMinute = 0;
973 int eventStartSecond = 0;
974 int eventStartDuration = 0;
975 std::string eventString = "";
979 if (eventData.DateTimeStartData.size() < 16){
981 addResult.addEventResult = CDSENTRY_INVALIDFILE;
986 eventString = eventData.DateTimeStartData.substr(0,4);
988 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
990 eventStartYear = atoi(eventString.c_str());
994 addResult.addEventResult = CDSENTRY_INVALIDFILE;
999 eventString = eventData.DateTimeStartData.substr(4,2);
1001 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1003 eventStartMonth = atoi(eventString.c_str());
1007 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1012 eventString = eventData.DateTimeStartData.substr(6,2);
1014 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1016 eventStartDay = atoi(eventString.c_str());
1020 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1025 eventString = eventData.DateTimeStartData.substr(9,2);
1027 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1029 eventStartHour = atoi(eventString.c_str());
1033 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1038 eventString = eventData.DateTimeStartData.substr(11,2);
1040 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1042 eventStartMinute = atoi(eventString.c_str());
1046 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1051 eventString = eventData.DateTimeStartData.substr(13,2);
1053 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1055 eventStartSecond = atoi(eventString.c_str());
1059 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1064 //eventYear = eventStartDate.substr(0, 4);
1068 int eventEndYear = 0;
1069 int eventEndMonth = 0;
1070 int eventEndDay = 0;
1071 int eventEndHour = 0;
1072 int eventEndMinute = 0;
1073 int eventEndSecond = 0;
1074 int eventEndDuration = 0;
1076 if (eventData.DateTimeEndData != ""){
1078 if (eventData.DateTimeEndData.size() < 16){
1080 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1085 eventString = eventData.DateTimeEndData.substr(0,4);
1087 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1089 eventEndYear = atoi(eventString.c_str());
1093 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1098 eventString = eventData.DateTimeEndData.substr(4,2);
1100 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1102 eventEndMonth = atoi(eventString.c_str());
1106 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1111 eventString = eventData.DateTimeEndData.substr(6,2);
1113 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1115 eventEndDay = atoi(eventString.c_str());
1119 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1124 eventString = eventData.DateTimeEndData.substr(9,2);
1126 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1128 eventEndHour = atoi(eventString.c_str());
1132 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1137 eventString = eventData.DateTimeEndData.substr(11,2);
1139 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1141 eventEndMinute = atoi(eventString.c_str());
1145 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1150 eventString = eventData.DateTimeEndData.substr(13,2);
1152 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1154 eventEndSecond = atoi(eventString.c_str());
1158 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1165 eventString = eventData.DurationData;
1167 // Process the duration data.
1169 int eventDurationWeeks = 0;
1170 int eventDurationDays = 0;
1171 int eventDurationHours = 0;
1172 int eventDurationMinutes = 0;
1173 int eventDurationSeconds = 0;
1175 // Get the duration (if DTEND hasn't been specified).
1177 if (eventData.DurationData.size() > 0){
1179 bool FoundP = false;
1180 bool FoundW = false;
1181 bool DateTimeMode = false;
1183 std::string::iterator eventDataChar = eventData.DurationData.begin();
1184 std::string currentValue = "";
1186 if (*eventDataChar != 'P'){
1188 eventDataChar = eventData.DurationData.end();
1192 for(eventDataChar; eventDataChar != eventData.DurationData.end(); eventDataChar++){
1194 // Check if value is a digit.
1196 if (isdigit(*eventDataChar)){
1198 currentValue += *eventDataChar;
1202 // Check that the value matches one of the letters.
1204 if (*eventDataChar == 'W' && DateTimeMode == false){
1206 eventDurationWeeks = atoi(currentValue.c_str());
1208 } else if (*eventDataChar == 'D' && DateTimeMode == false){
1210 eventDurationDays = atoi(currentValue.c_str());
1212 } else if (*eventDataChar == 'T' && DateTimeMode == false){
1214 DateTimeMode = true;
1216 } else if (*eventDataChar == 'H'){
1218 eventDurationHours = atoi(currentValue.c_str());
1220 } else if (*eventDataChar == 'M'){
1222 eventDurationMinutes = atoi(currentValue.c_str());
1224 } else if (*eventDataChar == 'S'){
1226 eventDurationSeconds = atoi(currentValue.c_str());
1230 // Reset the current value.
1240 // Add the calendar entry.
1242 std::string sqlParameter = "INSERT INTO calendarentries (calendarid, entryname, entrydescription,"
1243 " entrystartyear, entrystartmonth, entrystartday, entrystarthour, entrystartminute, entrystartsecond,"
1244 " entryendyear, entryendmonth, entryendday, entryendhour, entryendminute, entryendsecond, "
1245 " entrydurationweek, entrydurationday, entrydurationhour, entrydurationminute, entrydurationsecond, "
1247 " VALUES ((?1), (?2), (?3), (?4), (?5), (?6), (?7), (?8), (?9), (?10), "
1248 " (?11), (?12), (?13), (?14), (?15), (?16), (?17), (?18), (?19), (?20), (?21))";
1250 resultCode = sqlite3_prepare_v2(db, sqlParameter.c_str(), -1, &statementHandle, nullptr);
1252 resultCode = sqlite3_bind_int(statementHandle, 1, calendarID);
1254 if (resultCode != 0){
1255 addResult.addEventResult = CDSENTRY_FAILED;
1259 // Process Entry Name.
1261 resultCode = sqlite3_bind_text(statementHandle, 2, eventData.SummaryData.c_str(), -1, SQLITE_STATIC);
1263 if (resultCode != 0){
1264 addResult.addEventResult = CDSENTRY_FAILED;
1268 // Process Entry Description.
1270 string eventDescription;
1273 eventDescription = eventData.DescriptionList.at(0);
1276 catch (out_of_range &err){
1277 eventDescription = "";
1280 resultCode = sqlite3_bind_text(statementHandle, 3, eventDescription.c_str(), -1, SQLITE_STATIC);
1282 if (resultCode != 0){
1283 addResult.addEventResult = CDSENTRY_FAILED;
1287 // Process Entry Start Date information.
1289 resultCode = sqlite3_bind_int(statementHandle, 4, eventStartYear);
1291 if (resultCode != 0){
1292 addResult.addEventResult = CDSENTRY_FAILED;
1296 resultCode = sqlite3_bind_int(statementHandle, 5, eventStartMonth);
1298 if (resultCode != 0){
1299 addResult.addEventResult = CDSENTRY_FAILED;
1303 resultCode = sqlite3_bind_int(statementHandle, 6, eventStartDay);
1305 if (resultCode != 0){
1306 addResult.addEventResult = CDSENTRY_FAILED;
1310 resultCode = sqlite3_bind_int(statementHandle, 7, eventStartHour);
1312 if (resultCode != 0){
1313 addResult.addEventResult = CDSENTRY_FAILED;
1317 resultCode = sqlite3_bind_int(statementHandle, 8, eventStartMinute);
1319 if (resultCode != 0){
1320 addResult.addEventResult = CDSENTRY_FAILED;
1324 resultCode = sqlite3_bind_int(statementHandle, 9, eventStartSecond);
1326 if (resultCode != 0){
1327 addResult.addEventResult = CDSENTRY_FAILED;
1331 // Process Entry Start End information.
1333 resultCode = sqlite3_bind_int(statementHandle, 10, eventEndYear);
1335 if (resultCode != 0){
1336 addResult.addEventResult = CDSENTRY_FAILED;
1340 resultCode = sqlite3_bind_int(statementHandle, 11, eventEndMonth);
1342 if (resultCode != 0){
1343 addResult.addEventResult = CDSENTRY_FAILED;
1347 resultCode = sqlite3_bind_int(statementHandle, 12, eventEndDay);
1349 if (resultCode != 0){
1350 addResult.addEventResult = CDSENTRY_FAILED;
1354 resultCode = sqlite3_bind_int(statementHandle, 13, eventEndHour);
1356 if (resultCode != 0){
1357 addResult.addEventResult = CDSENTRY_FAILED;
1361 resultCode = sqlite3_bind_int(statementHandle, 14, eventEndMinute);
1363 if (resultCode != 0){
1364 addResult.addEventResult = CDSENTRY_FAILED;
1368 resultCode = sqlite3_bind_int(statementHandle, 15, eventEndSecond);
1370 if (resultCode != 0){
1371 addResult.addEventResult = CDSENTRY_FAILED;
1375 resultCode = sqlite3_bind_int(statementHandle, 16, eventDurationWeeks);
1377 if (resultCode != 0){
1378 addResult.addEventResult = CDSENTRY_FAILED;
1382 resultCode = sqlite3_bind_int(statementHandle, 17, eventDurationDays);
1384 if (resultCode != 0){
1385 addResult.addEventResult = CDSENTRY_FAILED;
1389 resultCode = sqlite3_bind_int(statementHandle, 18, eventDurationHours);
1391 if (resultCode != 0){
1392 addResult.addEventResult = CDSENTRY_FAILED;
1396 resultCode = sqlite3_bind_int(statementHandle, 19, eventDurationMinutes);
1398 if (resultCode != 0){
1399 addResult.addEventResult = CDSENTRY_FAILED;
1403 resultCode = sqlite3_bind_int(statementHandle, 20, eventDurationSeconds);
1405 if (resultCode != 0){
1406 addResult.addEventResult = CDSENTRY_FAILED;
1410 resultCode = sqlite3_bind_text(statementHandle, 21, filename.c_str(), -1, SQLITE_STATIC);
1412 if (resultCode != 0){
1413 addResult.addEventResult = CDSENTRY_FAILED;
1417 resultCode = sqlite3_step(statementHandle);
1419 if (resultCode != SQLITE_DONE){
1420 addResult.addEventResult = CDSENTRY_FAILED;
1424 addResult.calendarEntryID = sqlite3_last_insert_rowid(db);
1425 addResult.addEventResult = CDSENTRY_OK;
1427 // Update the checksum.
1429 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
1435 CDSEditEntryResult CalendarDataStorage::UpdateEvent(int eventID, std::string filename)
1438 CDSEditEntryResult editResult;
1439 editResult.editEventResult = CDSENTRY_UNITTESTFAIL;
1441 // Load the event file.
1443 CalendarEventObject eventData;
1444 CalendarObjectLoadResult eventLoadResult = eventData.LoadFile(filename);
1446 // Check the result of the event file load.
1448 switch (eventLoadResult){
1450 case CALENDAROBJECTLOAD_OK:
1452 case CALENDAROBJECTLOAD_MISSING:
1453 editResult.editEventResult = CDSENTRY_MISSINGFILE;
1455 case CALENDAROBJECTLOAD_INVALIDFORMAT:
1456 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1458 case CALENDAROBJECTLOAD_CANNOTOPEN:
1459 editResult.editEventResult = CDSENTRY_CANNOTOPENFILE;
1464 // Check if event exists first.
1468 sqlite3_stmt *findHandle;
1469 sqlite3_stmt *statementHandle;
1471 resultCode = sqlite3_prepare_v2(db, "SELECT id from calendarentries WHERE id=(?1);", -1, &findHandle, nullptr);
1473 if (resultCode != 0){
1474 editResult.editEventResult = CDSENTRY_FAILED;
1478 resultCode = sqlite3_bind_int(findHandle, 1, eventID);
1480 if (resultCode != 0){
1481 editResult.editEventResult = CDSENTRY_FAILED;
1485 resultCode = sqlite3_step(findHandle);
1487 if (resultCode == SQLITE_ROW){
1489 } else if (resultCode == SQLITE_DONE) {
1490 editResult.editEventResult = CDSENTRY_NOENTRY;
1493 editResult.editEventResult = CDSENTRY_FAILED;
1497 // Get the required values from the event object.
1499 int eventStartYear = 0;
1500 int eventStartMonth = 0;
1501 int eventStartDay = 0;
1502 int eventStartHour = 0;
1503 int eventStartMinute = 0;
1504 int eventStartSecond = 0;
1505 int eventStartDuration = 0;
1506 std::string eventString = "";
1510 if (eventData.DateTimeStartData.size() < 16){
1512 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1517 eventString = eventData.DateTimeStartData.substr(0,4);
1519 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1521 eventStartYear = atoi(eventString.c_str());
1525 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1530 eventString = eventData.DateTimeStartData.substr(4,2);
1532 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1534 eventStartMonth = atoi(eventString.c_str());
1538 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1543 eventString = eventData.DateTimeStartData.substr(6,2);
1545 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1547 eventStartDay = atoi(eventString.c_str());
1551 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1556 eventString = eventData.DateTimeStartData.substr(9,2);
1558 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1560 eventStartHour = atoi(eventString.c_str());
1564 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1569 eventString = eventData.DateTimeStartData.substr(11,2);
1571 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1573 eventStartMinute = atoi(eventString.c_str());
1577 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1582 eventString = eventData.DateTimeStartData.substr(13,2);
1584 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1586 eventStartSecond = atoi(eventString.c_str());
1590 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1595 //eventYear = eventStartDate.substr(0, 4);
1599 int eventEndYear = 0;
1600 int eventEndMonth = 0;
1601 int eventEndDay = 0;
1602 int eventEndHour = 0;
1603 int eventEndMinute = 0;
1604 int eventEndSecond = 0;
1605 int eventEndDuration = 0;
1607 if (eventData.DateTimeEndData != ""){
1609 if (eventData.DateTimeEndData.size() < 16){
1611 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1616 eventString = eventData.DateTimeEndData.substr(0,4);
1618 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1620 eventEndYear = atoi(eventString.c_str());
1624 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1629 eventString = eventData.DateTimeEndData.substr(4,2);
1631 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1633 eventEndMonth = atoi(eventString.c_str());
1637 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1642 eventString = eventData.DateTimeEndData.substr(6,2);
1644 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1646 eventEndDay = atoi(eventString.c_str());
1650 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1655 eventString = eventData.DateTimeEndData.substr(9,2);
1657 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1659 eventEndHour = atoi(eventString.c_str());
1663 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1668 eventString = eventData.DateTimeEndData.substr(11,2);
1670 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1672 eventEndMinute = atoi(eventString.c_str());
1676 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1681 eventString = eventData.DateTimeEndData.substr(13,2);
1683 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1685 eventEndSecond = atoi(eventString.c_str());
1689 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1696 eventString = eventData.DurationData;
1698 // Process the duration data.
1700 int eventDurationWeeks = 0;
1701 int eventDurationDays = 0;
1702 int eventDurationHours = 0;
1703 int eventDurationMinutes = 0;
1704 int eventDurationSeconds = 0;
1706 // Get the duration (if DTEND hasn't been specified).
1708 if (eventData.DurationData.size() > 0){
1710 bool FoundP = false;
1711 bool FoundW = false;
1712 bool DateTimeMode = false;
1714 std::string::iterator eventDataChar = eventData.DurationData.begin();
1715 std::string currentValue = "";
1717 if (*eventDataChar != 'P'){
1719 eventDataChar = eventData.DurationData.end();
1723 for(eventDataChar; eventDataChar != eventData.DurationData.end(); eventDataChar++){
1725 // Check if value is a digit.
1727 if (isdigit(*eventDataChar)){
1729 currentValue += *eventDataChar;
1733 // Check that the value matches one of the letters.
1735 if (*eventDataChar == 'W' && DateTimeMode == false){
1737 eventDurationWeeks = atoi(currentValue.c_str());
1739 } else if (*eventDataChar == 'D' && DateTimeMode == false){
1741 eventDurationDays = atoi(currentValue.c_str());
1743 } else if (*eventDataChar == 'T' && DateTimeMode == false){
1745 DateTimeMode = true;
1747 } else if (*eventDataChar == 'H'){
1749 eventDurationHours = atoi(currentValue.c_str());
1751 } else if (*eventDataChar == 'M'){
1753 eventDurationMinutes = atoi(currentValue.c_str());
1755 } else if (*eventDataChar == 'S'){
1757 eventDurationSeconds = atoi(currentValue.c_str());
1761 // Reset the current value.
1771 // Add the calendar entry.
1773 std::string sqlParameter = "UPDATE calendarentries SET entryname=(?2), entrydescription=(?3),"
1774 " entrystartyear=(?4), entrystartmonth=(?5), entrystartday=(?6), entrystarthour=(?7), entrystartminute=(?8), entrystartsecond=(?9),"
1775 " entryendyear=(?10), entryendmonth=(?11), entryendday=(?12), entryendhour=(?13), entryendminute=(?14), entryendsecond=(?15), "
1776 " entrydurationweek=(?16), entrydurationday=(?17), entrydurationhour=(?18), entrydurationminute=(?19), entrydurationsecond=(?20), "
1779 resultCode = sqlite3_prepare_v2(db, sqlParameter.c_str(), -1, &statementHandle, nullptr);
1781 resultCode = sqlite3_bind_int(statementHandle, 1, eventID);
1783 if (resultCode != 0){
1784 editResult.editEventResult = CDSENTRY_FAILED;
1788 // Process Entry Name.
1790 resultCode = sqlite3_bind_text(statementHandle, 2, eventData.SummaryData.c_str(), -1, SQLITE_STATIC);
1792 if (resultCode != 0){
1793 editResult.editEventResult = CDSENTRY_FAILED;
1797 // Process Entry Description.
1799 string eventDescription;
1802 eventDescription = eventData.DescriptionList.at(0);
1805 catch (out_of_range &err){
1806 eventDescription = "";
1809 resultCode = sqlite3_bind_text(statementHandle, 3, eventDescription.c_str(), -1, SQLITE_STATIC);
1811 if (resultCode != 0){
1812 editResult.editEventResult = CDSENTRY_FAILED;
1816 // Process Entry Start Date information.
1818 resultCode = sqlite3_bind_int(statementHandle, 4, eventStartYear);
1820 if (resultCode != 0){
1821 editResult.editEventResult = CDSENTRY_FAILED;
1825 resultCode = sqlite3_bind_int(statementHandle, 5, eventStartMonth);
1827 if (resultCode != 0){
1828 editResult.editEventResult = CDSENTRY_FAILED;
1832 resultCode = sqlite3_bind_int(statementHandle, 6, eventStartDay);
1834 if (resultCode != 0){
1835 editResult.editEventResult = CDSENTRY_FAILED;
1839 resultCode = sqlite3_bind_int(statementHandle, 7, eventStartHour);
1841 if (resultCode != 0){
1842 editResult.editEventResult = CDSENTRY_FAILED;
1846 resultCode = sqlite3_bind_int(statementHandle, 8, eventStartMinute);
1848 if (resultCode != 0){
1849 editResult.editEventResult = CDSENTRY_FAILED;
1853 resultCode = sqlite3_bind_int(statementHandle, 9, eventStartSecond);
1855 if (resultCode != 0){
1856 editResult.editEventResult = CDSENTRY_FAILED;
1860 // Process Entry Start End information.
1862 resultCode = sqlite3_bind_int(statementHandle, 10, eventEndYear);
1864 if (resultCode != 0){
1865 editResult.editEventResult = CDSENTRY_FAILED;
1869 resultCode = sqlite3_bind_int(statementHandle, 11, eventEndMonth);
1871 if (resultCode != 0){
1872 editResult.editEventResult = CDSENTRY_FAILED;
1876 resultCode = sqlite3_bind_int(statementHandle, 12, eventEndDay);
1878 if (resultCode != 0){
1879 editResult.editEventResult = CDSENTRY_FAILED;
1883 resultCode = sqlite3_bind_int(statementHandle, 13, eventEndHour);
1885 if (resultCode != 0){
1886 editResult.editEventResult = CDSENTRY_FAILED;
1890 resultCode = sqlite3_bind_int(statementHandle, 14, eventEndMinute);
1892 if (resultCode != 0){
1893 editResult.editEventResult = CDSENTRY_FAILED;
1897 resultCode = sqlite3_bind_int(statementHandle, 15, eventEndSecond);
1899 if (resultCode != 0){
1900 editResult.editEventResult = CDSENTRY_FAILED;
1904 resultCode = sqlite3_bind_int(statementHandle, 16, eventDurationWeeks);
1906 if (resultCode != 0){
1907 editResult.editEventResult = CDSENTRY_FAILED;
1911 resultCode = sqlite3_bind_int(statementHandle, 17, eventDurationDays);
1913 if (resultCode != 0){
1914 editResult.editEventResult = CDSENTRY_FAILED;
1918 resultCode = sqlite3_bind_int(statementHandle, 18, eventDurationHours);
1920 if (resultCode != 0){
1921 editResult.editEventResult = CDSENTRY_FAILED;
1925 resultCode = sqlite3_bind_int(statementHandle, 19, eventDurationMinutes);
1927 if (resultCode != 0){
1928 editResult.editEventResult = CDSENTRY_FAILED;
1932 resultCode = sqlite3_bind_int(statementHandle, 20, eventDurationSeconds);
1934 if (resultCode != 0){
1935 editResult.editEventResult = CDSENTRY_FAILED;
1939 resultCode = sqlite3_step(statementHandle);
1941 if (resultCode != SQLITE_DONE){
1942 editResult.editEventResult = CDSENTRY_FAILED;
1946 editResult.calendarEntryID = sqlite3_last_insert_rowid(db);
1947 editResult.editEventResult = CDSENTRY_OK;
1949 // Update the checksum.
1951 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
1957 CDSGetCalendarEntryInfo CalendarDataStorage::GetEvent(int calendarEntryID)
1960 CDSGetCalendarEntryInfo entryResult;
1962 // Check if the calendar entry exists.
1966 sqlite3_stmt *findHandle;
1967 sqlite3_stmt *statementHandle;
1969 resultCode = sqlite3_prepare_v2(db, "SELECT id FROM calendarentries WHERE id=(?1);", -1, &findHandle, nullptr);
1971 if (resultCode != 0){
1972 entryResult.getEventResult = CDSENTRY_FAILED;
1976 resultCode = sqlite3_bind_int(findHandle, 1, calendarEntryID);
1978 if (resultCode != 0){
1979 entryResult.getEventResult = CDSENTRY_FAILED;
1983 resultCode = sqlite3_step(findHandle);
1985 if (resultCode == SQLITE_ROW){
1987 } else if (resultCode == SQLITE_DONE) {
1988 entryResult.getEventResult = CDSENTRY_NOENTRY;
1991 entryResult.getEventResult = CDSENTRY_FAILED;
1995 // Get the calendar entry data.
1997 std::string sqlParameter = "SELECT entryname, entrydescription,"
1998 " entrystartyear, entrystartmonth, entrystartday, entrystarthour, entrystartminute, entrystartsecond,"
1999 " entryendyear, entryendmonth, entryendday, entryendhour, entryendminute, entryendsecond, "
2000 " entrydurationweek, entrydurationday, entrydurationhour, entrydurationminute, entrydurationsecond, "
2001 " calendarid, id, filename"
2002 " FROM calendarentries WHERE id=(?1)";
2004 resultCode = sqlite3_prepare_v2(db, sqlParameter.c_str(), -1, &statementHandle, nullptr);
2006 if (resultCode != 0){
2007 entryResult.getEventResult = CDSENTRY_FAILED;
2011 resultCode = sqlite3_bind_int(statementHandle, 1, calendarEntryID);
2013 if (resultCode != 0){
2014 entryResult.getEventResult = CDSENTRY_FAILED;
2018 resultCode = sqlite3_step(statementHandle);
2020 if (resultCode == SQLITE_ROW){
2022 // Get the calendar entry name,
2024 stringstream entryStream;
2026 entryStream << sqlite3_column_text(statementHandle, 0);
2027 entryResult.entryName = entryStream.str();
2029 entryStream.str("");
2031 // Get the calendar entry description.
2033 entryStream << sqlite3_column_text(statementHandle, 1);
2034 entryResult.entryDescription = entryStream.str();
2036 entryStream.str("");
2038 // Get the calendar entry filename.
2040 entryStream << sqlite3_column_text(statementHandle, 21);
2041 entryResult.entryFilename = entryStream.str();
2043 entryStream.str("");
2045 entryResult.entryStartYear = sqlite3_column_int(statementHandle, 2);
2046 entryResult.entryStartMonth = sqlite3_column_int(statementHandle, 3);
2047 entryResult.entryStartDay = sqlite3_column_int(statementHandle, 4);
2048 entryResult.entryStartHour = sqlite3_column_int(statementHandle, 5);
2049 entryResult.entryStartMinute = sqlite3_column_int(statementHandle, 6);
2050 entryResult.entryStartSecond = sqlite3_column_int(statementHandle, 7);
2051 entryResult.entryEndYear = sqlite3_column_int(statementHandle, 8);
2052 entryResult.entryEndMonth = sqlite3_column_int(statementHandle, 9);
2053 entryResult.entryEndDay = sqlite3_column_int(statementHandle, 10);
2054 entryResult.entryEndHour = sqlite3_column_int(statementHandle, 11);
2055 entryResult.entryEndMinute = sqlite3_column_int(statementHandle, 12);
2056 entryResult.entryEndSecond = sqlite3_column_int(statementHandle, 13);
2057 entryResult.entryDurationWeeks = sqlite3_column_int(statementHandle, 14);
2058 entryResult.entryDurationDays = sqlite3_column_int(statementHandle, 15);
2059 entryResult.entryDurationHours = sqlite3_column_int(statementHandle, 16);
2060 entryResult.entryDurationMinutes = sqlite3_column_int(statementHandle, 17);
2061 entryResult.entryDurationSeconds = sqlite3_column_int(statementHandle, 18);
2062 entryResult.calendarID = sqlite3_column_int(statementHandle, 19);
2063 entryResult.calendarEntryID = sqlite3_column_int(statementHandle, 20);
2065 } else if (resultCode == SQLITE_DONE) {
2066 entryResult.getEventResult = CDSENTRY_NOCALENDAR;
2069 entryResult.getEventResult = CDSENTRY_FAILED;
2073 entryResult.getEventResult = CDSENTRY_OK;
2079 CDSEntryResult CalendarDataStorage::DeleteEvent(int calendarEntryID)
2082 CDSEntryResult deleteResult = CDSENTRY_UNITTESTFAIL;
2084 // Check if the calendar entry exists.
2088 sqlite3_stmt *findHandle;
2089 sqlite3_stmt *statementHandle;
2091 resultCode = sqlite3_prepare_v2(db, "SELECT id FROM calendarentries WHERE id=(?1);", -1, &findHandle, nullptr);
2093 if (resultCode != 0){
2094 return CDSENTRY_FAILED;
2097 resultCode = sqlite3_bind_int(findHandle, 1, calendarEntryID);
2099 if (resultCode != 0){
2100 return CDSENTRY_FAILED;
2103 resultCode = sqlite3_step(findHandle);
2105 if (resultCode == SQLITE_ROW){
2107 } else if (resultCode == SQLITE_DONE) {
2108 return CDSENTRY_NOENTRY;
2110 return CDSENTRY_FAILED;
2113 // Delete the account.
2115 resultCode = sqlite3_prepare_v2(db, "DELETE FROM calendarentries WHERE id=(?1);", -1, &statementHandle, nullptr);
2117 if (resultCode != 0){
2118 return CDSENTRY_FAILED;
2121 resultCode = sqlite3_bind_int(statementHandle, 1, calendarEntryID);
2123 if (resultCode != 0){
2124 return CDSENTRY_FAILED;
2127 resultCode = sqlite3_step(statementHandle);
2129 if (resultCode == SQLITE_DONE){
2130 deleteResult = CDSENTRY_OK;
2132 return CDSENTRY_FAILED;
2135 // Update the checksum.
2137 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
2139 return deleteResult;
2143 CDSEntryList CalendarDataStorage::GetEventList(int calendarID){
2145 CDSEntryList entryList;
2146 entryList.getEventListResult = CDSENTRY_UNITTESTFAIL;
2148 // Check if calendar exists first.
2152 sqlite3_stmt *findHandle;
2153 sqlite3_stmt *calendarHandle;
2155 resultCode = sqlite3_prepare_v2(db, "SELECT id from calendars WHERE id=(?1);", -1, &findHandle, nullptr);
2157 if (resultCode != 0){
2158 entryList.getEventListResult = CDSENTRY_FAILED;
2162 resultCode = sqlite3_bind_int(findHandle, 1, calendarID);
2164 if (resultCode != 0){
2165 entryList.getEventListResult = CDSENTRY_FAILED;
2169 resultCode = sqlite3_step(findHandle);
2171 if (resultCode == SQLITE_ROW){
2173 } else if (resultCode == SQLITE_DONE) {
2174 entryList.getEventListResult = CDSENTRY_NOCALENDAR;
2177 entryList.getEventListResult = CDSENTRY_FAILED;
2181 // Get the list of entry IDs.
2183 resultCode = sqlite3_prepare_v2(db, "SELECT id FROM calendarentries WHERE calendarid=(?1);", -1, &calendarHandle, nullptr);
2185 if (resultCode != 0){
2186 entryList.getEventListResult = CDSENTRY_FAILED;
2190 resultCode = sqlite3_bind_int(calendarHandle, 1, calendarID);
2192 if (resultCode != 0){
2193 entryList.getEventListResult = CDSENTRY_FAILED;
2197 resultCode = sqlite3_step(calendarHandle);
2199 if (resultCode == SQLITE_DONE || resultCode == SQLITE_ROW){
2201 entryList.getEventListResult = CDSENTRY_FAILED;
2205 while (resultCode == SQLITE_ROW){
2207 int calendarID = sqlite3_column_int(calendarHandle, 0);
2209 entryList.entryList.push_back(calendarID);
2211 resultCode = sqlite3_step(calendarHandle);
2215 entryList.getEventListResult = CDSENTRY_OK;
2221 CDSEntryList CalendarDataStorage::GetEventListByDate(int calendarYear, int calendarMonth, int calendarDay){
2223 CDSEntryList entryList;
2224 entryList.getEventListResult = CDSENTRY_UNITTESTFAIL;
2226 // Check if calendar exists first.
2230 sqlite3_stmt *calendarHandle;
2232 // Get the list of entry IDs.
2234 resultCode = sqlite3_prepare_v2(db, "SELECT id FROM calendarentries WHERE entrystartyear=(?1) AND entrystartmonth=(?2) AND entrystartday=(?3);", -1, &calendarHandle, nullptr);
2236 if (resultCode != 0){
2237 entryList.getEventListResult = CDSENTRY_FAILED;
2241 resultCode = sqlite3_bind_int(calendarHandle, 1, calendarYear);
2243 if (resultCode != 0){
2244 entryList.getEventListResult = CDSENTRY_FAILED;
2248 resultCode = sqlite3_bind_int(calendarHandle, 2, calendarMonth);
2250 if (resultCode != 0){
2251 entryList.getEventListResult = CDSENTRY_FAILED;
2255 resultCode = sqlite3_bind_int(calendarHandle, 3, calendarDay);
2257 if (resultCode != 0){
2258 entryList.getEventListResult = CDSENTRY_FAILED;
2262 resultCode = sqlite3_step(calendarHandle);
2264 if (resultCode == SQLITE_DONE || resultCode == SQLITE_ROW){
2266 entryList.getEventListResult = CDSENTRY_FAILED;
2270 while (resultCode == SQLITE_ROW){
2272 int calendarID = sqlite3_column_int(calendarHandle, 0);
2274 entryList.entryList.push_back(calendarID);
2276 resultCode = sqlite3_step(calendarHandle);
2280 entryList.getEventListResult = CDSENTRY_OK;
2286 CDSCalendarList CalendarDataStorage::GetCalendarList(int accountID){
2288 CDSCalendarList calendarList;
2289 calendarList.getCalendarListResult = CDSCALENDAR_UNITTESTFAIL;
2291 // Check if calendar exists first.
2295 sqlite3_stmt *findHandle;
2296 sqlite3_stmt *calendarHandle;
2298 resultCode = sqlite3_prepare_v2(db, "SELECT id from accounts WHERE id=(?1);", -1, &findHandle, nullptr);
2300 if (resultCode != 0){
2301 calendarList.getCalendarListResult = CDSCALENDAR_FAILED;
2302 return calendarList;
2305 resultCode = sqlite3_bind_int(findHandle, 1, accountID);
2307 if (resultCode != 0){
2308 calendarList.getCalendarListResult = CDSCALENDAR_FAILED;
2309 return calendarList;
2312 resultCode = sqlite3_step(findHandle);
2314 if (resultCode == SQLITE_ROW){
2316 } else if (resultCode == SQLITE_DONE) {
2317 calendarList.getCalendarListResult = CDSCALENDAR_NOCALENDAR;
2318 return calendarList;
2320 calendarList.getCalendarListResult = CDSCALENDAR_FAILED;
2321 return calendarList;
2324 // Get the list of entry IDs.
2326 resultCode = sqlite3_prepare_v2(db, "SELECT id, calendarid FROM calendars WHERE accountid=(?1);", -1, &calendarHandle, nullptr);
2328 if (resultCode != 0){
2329 calendarList.getCalendarListResult = CDSCALENDAR_FAILED;
2330 return calendarList;
2333 resultCode = sqlite3_bind_int(calendarHandle, 1, accountID);
2335 if (resultCode != 0){
2336 calendarList.getCalendarListResult = CDSCALENDAR_FAILED;
2337 return calendarList;
2340 resultCode = sqlite3_step(calendarHandle);
2342 if (resultCode == SQLITE_DONE || resultCode == SQLITE_ROW){
2344 calendarList.getCalendarListResult = CDSCALENDAR_FAILED;
2345 return calendarList;
2348 while (resultCode == SQLITE_ROW){
2350 int calendarID = sqlite3_column_int(calendarHandle, 0);
2352 stringstream calendarStream;
2354 calendarStream << sqlite3_column_text(calendarHandle, 1);
2356 calendarList.calendarList.push_back(calendarID);
2357 calendarList.calendarListTextID.push_back(calendarStream.str());
2359 calendarStream.str("");
2361 resultCode = sqlite3_step(calendarHandle);
2365 calendarList.getCalendarListResult = CDSCALENDAR_OK;
2367 return calendarList;
2371 CDSChecksumResult CalendarDataStorage::AddChecksum(string checksumName, string checksumValue){
2375 // Check if the checksum already exists.
2377 sqlite3_stmt *findHandle;
2378 sqlite3_stmt *checksumHandle;
2380 resultCode = sqlite3_prepare_v2(db, "SELECT checksumvalue from checksums WHERE checksumname=(?1);", -1, &findHandle, nullptr);
2382 if (resultCode != 0){
2383 return CDSCHECKSUM_FAILED;
2386 resultCode = sqlite3_bind_text(findHandle, 1, checksumName.c_str(), -1, SQLITE_STATIC);
2388 if (resultCode != 0){
2389 return CDSCHECKSUM_FAILED;
2392 resultCode = sqlite3_step(findHandle);
2394 if (resultCode == SQLITE_ROW){
2395 return CDSCHECKSUM_CHECKSUMALREADYEXISTS;
2396 } else if (resultCode == SQLITE_DONE) {
2399 return CDSCHECKSUM_FAILED;
2402 // Add the checksum to the checksum table.
2404 resultCode = sqlite3_prepare_v2(db, "INSERT INTO checksums (checksumname, checksumvalue) VALUES(?1, ?2);", -1, &checksumHandle, nullptr);
2406 if (resultCode != 0){
2407 return CDSCHECKSUM_FAILED;
2410 resultCode = sqlite3_bind_text(checksumHandle, 1, checksumName.c_str(), -1, SQLITE_STATIC);
2412 if (resultCode != 0){
2413 return CDSCHECKSUM_FAILED;
2416 resultCode = sqlite3_bind_text(checksumHandle, 2, checksumValue.c_str(), -1, SQLITE_STATIC);
2418 if (resultCode != 0){
2419 return CDSCHECKSUM_FAILED;
2422 resultCode = sqlite3_step(checksumHandle);
2424 if (resultCode != SQLITE_DONE){
2425 return CDSCHECKSUM_FAILED;
2428 return CDSCHECKSUM_OK;
2432 CDSGetChecksumResult CalendarDataStorage::GetChecksum(string checksumName){
2434 CDSGetChecksumResult getChecksumResult;
2438 // Check if the checksum already exists.
2440 sqlite3_stmt *getHandle;
2442 resultCode = sqlite3_prepare_v2(db, "SELECT checksumvalue from checksums WHERE checksumname=(?1);", -1, &getHandle, nullptr);
2444 if (resultCode != 0){
2445 getChecksumResult.getChecksumResult = CDSCHECKSUM_FAILED;
2446 return getChecksumResult;
2449 resultCode = sqlite3_bind_text(getHandle, 1, checksumName.c_str(), -1, SQLITE_STATIC);
2451 if (resultCode != 0){
2452 getChecksumResult.getChecksumResult = CDSCHECKSUM_FAILED;
2453 return getChecksumResult;
2456 resultCode = sqlite3_step(getHandle);
2458 if (resultCode == SQLITE_ROW){
2459 } else if (resultCode == SQLITE_DONE) {
2460 getChecksumResult.getChecksumResult = CDSCHECKSUM_NOHASH;
2461 return getChecksumResult;
2463 getChecksumResult.getChecksumResult = CDSCHECKSUM_FAILED;
2464 return getChecksumResult;
2467 stringstream checksumStream;
2469 checksumStream << sqlite3_column_text(getHandle, 0);
2471 getChecksumResult.checksumValue = checksumStream.str();
2473 getChecksumResult.getChecksumResult = CDSCHECKSUM_OK;
2475 return getChecksumResult;
2479 CDSChecksumResult CalendarDataStorage::UpdateChecksum(std::string checksumName, std::string checksumValue){
2483 // Check if the checksum already exists.
2485 sqlite3_stmt *getHandle;
2486 sqlite3_stmt *statementHandle;
2488 resultCode = sqlite3_prepare_v2(db, "SELECT checksumvalue from checksums WHERE checksumname=(?1);", -1, &getHandle, nullptr);
2490 if (resultCode != 0){
2491 return CDSCHECKSUM_FAILED;
2494 resultCode = sqlite3_bind_text(getHandle, 1, checksumName.c_str(), -1, SQLITE_STATIC);
2496 if (resultCode != 0){
2497 return CDSCHECKSUM_FAILED;
2500 resultCode = sqlite3_step(getHandle);
2502 if (resultCode == SQLITE_ROW){
2503 } else if (resultCode == SQLITE_DONE) {
2504 return CDSCHECKSUM_NOHASH;
2506 return CDSCHECKSUM_FAILED;
2509 // Update the checksum.
2511 resultCode = sqlite3_prepare_v2(db, "UPDATE checksums SET checksumvalue=(?1) WHERE checksumname=(?2);", -1, &statementHandle, nullptr);
2513 if (resultCode != 0){
2514 return CDSCHECKSUM_FAILED;
2517 resultCode = sqlite3_bind_text(statementHandle, 1, checksumValue.c_str(), -1, SQLITE_STATIC);
2519 if (resultCode != 0){
2520 return CDSCHECKSUM_FAILED;
2523 resultCode = sqlite3_bind_text(statementHandle, 2, checksumName.c_str(), -1, SQLITE_STATIC);
2525 if (resultCode != 0){
2526 return CDSCHECKSUM_FAILED;
2529 resultCode = sqlite3_step(statementHandle);
2531 if (resultCode != SQLITE_DONE){
2532 return CDSCHECKSUM_FAILED;
2535 return CDSCHECKSUM_OK;
2539 CDSCleanupResult CalendarDataStorage::Clear(){
2541 // Remove all data from the tables and reset the sequence numbers.
2544 sqlite3_stmt *statementHandle;
2546 resultCode = sqlite3_prepare_v2(db, "DELETE FROM calendarentries", - 1, &statementHandle, nullptr);
2548 if (resultCode != 0){
2549 cout << "Fail 1" << endl;
2550 return CDSCLEANUP_FAILED;
2553 resultCode = sqlite3_step(statementHandle);
2555 if (resultCode != SQLITE_DONE){
2556 cout << "Fail 2" << endl;
2557 return CDSCLEANUP_FAILED;
2560 resultCode = sqlite3_prepare_v2(db, "DELETE FROM sqlite_sequence WHERE name='calendarentries';", -1, &statementHandle, nullptr);
2562 if (resultCode != 0){
2563 cout << "Fail 3" << endl;
2564 cout << sqlite3_errmsg(db) << endl;
2565 return CDSCLEANUP_FAILED;
2568 resultCode = sqlite3_step(statementHandle);
2570 if (resultCode != SQLITE_DONE){
2571 cout << "Fail 4" << endl;
2572 return CDSCLEANUP_FAILED;
2575 resultCode = sqlite3_prepare_v2(db, "DELETE FROM calendars", -1, &statementHandle, nullptr);
2577 if (resultCode != 0){
2578 cout << "Fail 5" << endl;
2579 return CDSCLEANUP_FAILED;
2582 resultCode = sqlite3_step(statementHandle);
2584 if (resultCode != SQLITE_DONE){
2585 cout << "Fail 6" << endl;
2586 return CDSCLEANUP_FAILED;
2589 resultCode = sqlite3_prepare_v2(db, "DELETE FROM sqlite_sequence WHERE name='calendars';", -1, &statementHandle, nullptr);
2591 if (resultCode != 0){
2592 cout << "Fail 7" << endl;
2593 return CDSCLEANUP_FAILED;
2596 resultCode = sqlite3_step(statementHandle);
2598 if (resultCode != SQLITE_DONE){
2599 cout << "Fail 8" << endl;
2600 return CDSCLEANUP_FAILED;
2603 resultCode = sqlite3_prepare_v2(db, "DELETE FROM accounts", -1, &statementHandle, nullptr);
2605 if (resultCode != 0){
2606 cout << "Fail 9" << endl;
2607 return CDSCLEANUP_FAILED;
2610 resultCode = sqlite3_step(statementHandle);
2612 if (resultCode != SQLITE_DONE){
2613 cout << "Fail 10" << endl;
2614 return CDSCLEANUP_FAILED;
2617 resultCode = sqlite3_prepare_v2(db, "DELETE FROM sqlite_sequence WHERE name='accounts'", -1, &statementHandle, nullptr);
2619 if (resultCode != 0){
2620 cout << "Fail 11" << endl;
2621 return CDSCLEANUP_FAILED;
2624 resultCode = sqlite3_step(statementHandle);
2626 if (resultCode != SQLITE_DONE){
2627 cout << "Fail 12" << endl;
2628 return CDSCLEANUP_FAILED;
2631 // Update the checksum.
2633 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
2635 return CDSCLEANUP_OK;