1 #include "CalendarDataStorage.h"
3 #define CDS_RANDOMPOW 24
9 static int callback(void *NotUsed, int argc, char **argv, char **azColName){
13 CalendarDataStorage::CalendarDataStorage(){
15 // Initialise the SQLite database.
17 sqlite3_open_v2(":memory:", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_FULLMUTEX, nullptr);
22 CalendarDataStorage::~CalendarDataStorage(){
24 // Destory the SQLite database.
30 void CalendarDataStorage::SetupTables(){
32 // Setup the tables for the Calendar Data Storage.
34 char *setupTablesErrMsg = nullptr;
37 // Setup the accounts table.
39 const char *accountsTableString;
40 accountsTableString = "CREATE TABLE accounts(id INTEGER PRIMARY KEY AUTOINCREMENT"
41 ", preferencesid INTEGER"
45 resultCode = sqlite3_exec(db, accountsTableString, callback, nullptr, &setupTablesErrMsg);
48 DataStorageInitOK = false;
52 // Setup the calendars table.
54 const char *calendarTableString;
55 calendarTableString = "CREATE TABLE calendars(id INTEGER PRIMARY KEY AUTOINCREMENT"
63 resultCode = sqlite3_exec(db, calendarTableString, callback, nullptr, &setupTablesErrMsg);
66 DataStorageInitOK = false;
70 // Setup the calendar entries table.
72 const char *calendarentriesTableString;
73 calendarentriesTableString = "CREATE TABLE calendarentries(id INTEGER PRIMARY KEY AUTOINCREMENT"
74 ", calendarid INTEGER"
76 ", entrydescription TEXT"
77 ", entrystartyear INTEGER"
78 ", entrystartmonth INTEGER"
79 ", entrystartday INTEGER"
80 ", entrystarthour INTEGER"
81 ", entrystartminute INTEGER"
82 ", entrystartsecond INTEGER"
83 ", entryendyear INTEGER"
84 ", entryendmonth INTEGER"
85 ", entryendday INTEGER"
86 ", entryendhour INTEGER"
87 ", entryendminute INTEGER"
88 ", entryendsecond INTEGER"
89 ", entrydurationweek INTEGER"
90 ", entrydurationday INTEGER"
91 ", entrydurationhour INTEGER"
92 ", entrydurationminute INTEGER"
93 ", entrydurationsecond INTEGER"
97 resultCode = sqlite3_exec(db, calendarentriesTableString, callback, nullptr, &setupTablesErrMsg);
100 DataStorageInitOK = false;
104 // Setup the checksums table.
106 const char *checksumsTableString;
107 checksumsTableString = "CREATE TABLE checksums(checksumname TEXT PRIMARY KEY "
108 ", checksumvalue TEXT);";
110 resultCode = sqlite3_exec(db, checksumsTableString, callback, nullptr, &setupTablesErrMsg);
112 if (resultCode != 0){
113 DataStorageInitOK = false;
117 // Setup internal checksums.
119 CDSChecksumResult addChecksum = AddChecksum("internal_updatedata", "");
121 if (addChecksum != CDSCHECKSUM_OK){
122 DataStorageInitOK = false;
126 DataStorageInitOK = true;
130 bool CalendarDataStorage::DidInitOK()
133 return DataStorageInitOK;
137 CDSAccountResult CalendarDataStorage::AddAccount(string accountName, int accountPreferencesID)
140 CDSAccountResult addResult = CDSACCOUNT_UNITTESTFAIL;
143 sqlite3_stmt *statementHandle;
145 resultCode = sqlite3_prepare_v2(db, "INSERT INTO accounts (name, preferencesid) VALUES(?1, ?2);", -1, &statementHandle, nullptr);
147 if (resultCode != 0){
148 return CDSACCOUNT_FAILED;
151 resultCode = sqlite3_bind_text(statementHandle, 1, accountName.c_str(), -1, SQLITE_STATIC);
153 if (resultCode != 0){
154 return CDSACCOUNT_FAILED;
157 resultCode = sqlite3_bind_int(statementHandle, 2, accountPreferencesID);
159 if (resultCode != 0){
160 return CDSACCOUNT_FAILED;
163 resultCode = sqlite3_step(statementHandle);
165 if (resultCode != SQLITE_DONE){
166 return CDSACCOUNT_FAILED;
169 // Update the checksum.
171 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
173 addResult = CDSACCOUNT_OK;
179 CDSAccountList CalendarDataStorage::GetAccountList()
182 CDSAccountList accountList;
184 // Check if calendar exists first.
188 sqlite3_stmt *statementHandle;
190 resultCode = sqlite3_prepare_v2(db, "SELECT id, name, preferencesid from accounts;", -1, &statementHandle, nullptr);
192 if (resultCode != 0){
193 accountList.getAccountListResult = CDSACCOUNT_FAILED;
197 if (resultCode != 0){
198 accountList.getAccountListResult = CDSACCOUNT_FAILED;
202 resultCode = sqlite3_step(statementHandle);
204 if (resultCode == SQLITE_ROW){
206 } else if (resultCode == SQLITE_DONE) {
207 accountList.getAccountListResult = CDSACCOUNT_NOACCOUNT;
210 accountList.getAccountListResult = CDSACCOUNT_FAILED;
214 while (resultCode == SQLITE_ROW){
216 CDSGetAccountInfo accountInfo;
218 accountInfo.accountID = sqlite3_column_int(statementHandle, 0);
219 accountInfo.accountPreferencesID = sqlite3_column_int(statementHandle, 2);
221 stringstream calendarStream;
223 calendarStream << sqlite3_column_text(statementHandle, 1);
225 accountInfo.accountName = calendarStream.str();
226 accountInfo.accountInfoResult = CDSACCOUNT_OK;
228 accountList.accountList.push_back(accountInfo);
230 resultCode = sqlite3_step(statementHandle);
234 accountList.getAccountListResult = CDSACCOUNT_OK;
240 CDSGetAccountInfo CalendarDataStorage::GetAccount(string accountName)
243 CDSGetAccountInfo accountInfo;
244 accountInfo.accountInfoResult = CDSACCOUNT_UNITTESTFAIL;
247 sqlite3_stmt *statementHandle;
249 resultCode = sqlite3_prepare_v2(db, "SELECT name, id, preferencesid FROM accounts WHERE name=(?1);", -1, &statementHandle, nullptr);
251 if (resultCode != 0){
252 accountInfo.accountInfoResult = CDSACCOUNT_FAILED;
256 resultCode = sqlite3_bind_text(statementHandle, 1, accountName.c_str(), -1, SQLITE_STATIC);
258 if (resultCode != 0){
259 accountInfo.accountInfoResult = CDSACCOUNT_FAILED;
263 resultCode = sqlite3_step(statementHandle);
265 if (resultCode == SQLITE_DONE){
267 accountInfo.accountInfoResult = CDSACCOUNT_NOACCOUNT;
270 } else if (resultCode == SQLITE_ROW){
272 // Get the result data.
274 stringstream accountNameStream;
276 accountNameStream << sqlite3_column_text(statementHandle, 0);
278 accountInfo.accountName = accountNameStream.str();
279 accountInfo.accountID = sqlite3_column_int(statementHandle, 1);
280 accountInfo.accountPreferencesID = sqlite3_column_int(statementHandle, 2);
282 accountInfo.accountInfoResult = CDSACCOUNT_OK;
287 accountInfo.accountInfoResult = CDSACCOUNT_FAILED;
296 CDSAccountResult CalendarDataStorage::UpdateAccount(int accountID, string accountName)
299 CDSAccountResult updateResult = CDSACCOUNT_UNITTESTFAIL;
302 sqlite3_stmt *findHandle;
303 sqlite3_stmt *statementHandle;
305 // Check if account exists first.
307 resultCode = sqlite3_prepare_v2(db, "SELECT id from accounts WHERE id=(?1);", -1, &findHandle, nullptr);
309 if (resultCode != 0){
310 return CDSACCOUNT_FAILED;
313 resultCode = sqlite3_bind_int(findHandle, 1, accountID);
315 if (resultCode != 0){
316 return CDSACCOUNT_FAILED;
319 resultCode = sqlite3_step(findHandle);
321 if (resultCode == SQLITE_ROW){
323 } else if (resultCode == SQLITE_DONE) {
324 return CDSACCOUNT_NOACCOUNT;
326 return CDSACCOUNT_FAILED;
329 // Update the account.
331 resultCode = sqlite3_prepare_v2(db, "UPDATE accounts SET name=(?1) WHERE id=(?2);", -1, &statementHandle, nullptr);
333 if (resultCode != 0){
334 return CDSACCOUNT_FAILED;
337 resultCode = sqlite3_bind_text(statementHandle, 1, accountName.c_str(), -1, SQLITE_STATIC);
339 if (resultCode != 0){
340 return CDSACCOUNT_FAILED;
343 resultCode = sqlite3_bind_int(statementHandle, 2, accountID);
345 if (resultCode != 0){
346 return CDSACCOUNT_FAILED;
349 resultCode = sqlite3_step(statementHandle);
351 if (resultCode != SQLITE_DONE){
352 return CDSACCOUNT_FAILED;
355 // Update the checksum.
357 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
359 updateResult = CDSACCOUNT_OK;
365 CDSAccountResult CalendarDataStorage::DeleteAccount(int accountID)
368 CDSAccountResult deleteResult = CDSACCOUNT_UNITTESTFAIL;
370 // Check if account exists first.
372 sqlite3_stmt *findHandle;
373 sqlite3_stmt *statementHandle;
374 sqlite3_stmt *calendarHandle;
377 resultCode = sqlite3_prepare_v2(db, "SELECT id from accounts WHERE id=(?1);", -1, &findHandle, nullptr);
379 if (resultCode != 0){
380 return CDSACCOUNT_FAILED;
383 resultCode = sqlite3_bind_int(findHandle, 1, accountID);
385 if (resultCode != 0){
386 return CDSACCOUNT_FAILED;
389 resultCode = sqlite3_step(findHandle);
391 if (resultCode == SQLITE_ROW){
393 } else if (resultCode == SQLITE_DONE) {
394 return CDSACCOUNT_NOACCOUNT;
396 return CDSACCOUNT_FAILED;
399 // Delete the account.
401 resultCode = sqlite3_prepare_v2(db, "DELETE FROM accounts WHERE id=(?1);", -1, &statementHandle, nullptr);
403 if (resultCode != 0){
404 return CDSACCOUNT_FAILED;
407 resultCode = sqlite3_bind_int(statementHandle, 1, accountID);
409 if (resultCode != 0){
410 return CDSACCOUNT_FAILED;
413 resultCode = sqlite3_step(statementHandle);
415 if (resultCode == SQLITE_DONE){
416 //deleteResult = CDSACCOUNT_OK;
418 return CDSACCOUNT_FAILED;
421 // Get the calendar IDs and delete each calendar (and associated entries).
423 resultCode = sqlite3_prepare_v2(db, "SELECT id FROM calendars WHERE accountid=(?1);", -1, &calendarHandle, nullptr);
425 if (resultCode != 0){
426 return CDSACCOUNT_FAILED;
429 resultCode = sqlite3_bind_int(calendarHandle, 1, accountID);
431 if (resultCode != 0){
432 return CDSACCOUNT_FAILED;
435 resultCode = sqlite3_step(calendarHandle);
437 if (resultCode == SQLITE_DONE || resultCode == SQLITE_ROW){
438 deleteResult = CDSACCOUNT_OK;
440 return CDSACCOUNT_FAILED;
443 while (resultCode == SQLITE_ROW){
445 int calendarDeleteID = sqlite3_column_int(calendarHandle, 0);
447 DeleteCalendar(calendarDeleteID);
449 resultCode = sqlite3_step(calendarHandle);
453 // Update the checksum.
455 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
457 deleteResult = CDSACCOUNT_OK;
464 CDSCalendarResult CalendarDataStorage::AddCalendar(int accountID, string calendarName, string calendarID, Colour calendarColour, string calendarDescription)
467 CDSCalendarResult addResult = CDSCALENDAR_UNITTESTFAIL;
470 sqlite3_stmt *statementHandle;
472 resultCode = sqlite3_prepare_v2(db, "INSERT INTO calendars (name, calendarid, accountid, colour, description) VALUES(?1, ?2, ?3, ?4, ?5);", -1, &statementHandle, nullptr);
474 if (resultCode != 0){
475 return CDSCALENDAR_FAILED;
478 resultCode = sqlite3_bind_text(statementHandle, 1, calendarName.c_str(), -1, SQLITE_STATIC);
480 if (resultCode != 0){
481 return CDSCALENDAR_FAILED;
484 resultCode = sqlite3_bind_text(statementHandle, 2, calendarID.c_str(), -1, SQLITE_STATIC);
486 if (resultCode != 0){
487 return CDSCALENDAR_FAILED;
490 resultCode = sqlite3_bind_int(statementHandle, 3, accountID);
492 if (resultCode != 0){
493 return CDSCALENDAR_FAILED;
496 resultCode = sqlite3_bind_text(statementHandle, 4, ((string)calendarColour).c_str(), -1, SQLITE_STATIC);
498 if (resultCode != 0){
499 return CDSCALENDAR_FAILED;
502 resultCode = sqlite3_bind_text(statementHandle, 5, calendarDescription.c_str(), -1, SQLITE_STATIC);
504 if (resultCode != 0){
505 return CDSCALENDAR_FAILED;
508 resultCode = sqlite3_step(statementHandle);
510 if (resultCode != SQLITE_DONE){
511 return CDSCALENDAR_FAILED;
514 // Update the checksum.
516 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
518 addResult = CDSCALENDAR_OK;
524 CDSGetCalendarInfo CalendarDataStorage::GetCalendar(std::string accountName, std::string calendarTextID)
527 CDSGetAccountInfo accountResult;
528 CDSGetCalendarInfo calendarResult;
529 sqlite3_stmt *statementHandle;
532 // Check if the account exists.
534 accountResult = GetAccount(accountName);
536 switch (accountResult.accountInfoResult){
539 calendarResult.accountName = accountResult.accountName;
540 calendarResult.accountInfoResult = CDSACCOUNT_OK;
542 case CDSACCOUNT_FAILED:
543 calendarResult.accountInfoResult = CDSACCOUNT_FAILED;
544 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
545 return calendarResult;
546 case CDSACCOUNT_NOACCOUNT:
547 calendarResult.accountInfoResult = CDSACCOUNT_NOACCOUNT;
548 calendarResult.calendarInfoResult = CDSCALENDAR_NOCALENDAR;
549 return calendarResult;
553 // Check if the calendar exists.
555 resultCode = sqlite3_prepare_v2(db, "SELECT id, accountid, name, calendarid, colour, description FROM calendars WHERE accountid=(?1) AND calendarid=(?2);", -1, &statementHandle, nullptr);
557 if (resultCode != 0){
558 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
559 return calendarResult;
562 resultCode = sqlite3_bind_int(statementHandle, 1, accountResult.accountID);
564 if (resultCode != 0){
565 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
566 return calendarResult;
569 resultCode = sqlite3_bind_text(statementHandle, 2, calendarTextID.c_str(), -1, SQLITE_STATIC);
571 if (resultCode != 0){
572 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
573 return calendarResult;
576 resultCode = sqlite3_step(statementHandle);
578 if (resultCode == SQLITE_DONE){
580 calendarResult.calendarInfoResult = CDSCALENDAR_NOCALENDAR;
581 return calendarResult;
583 } else if (resultCode == SQLITE_ROW){
585 // Get the calendar name.
587 stringstream calendarStream;
589 calendarStream << sqlite3_column_text(statementHandle, 2);
590 calendarResult.calendarName = calendarStream.str();
592 calendarStream.str("");
593 calendarStream << sqlite3_column_text(statementHandle, 3);
594 calendarResult.calendarTextID = calendarStream.str();
596 calendarStream.str("");
597 calendarStream << sqlite3_column_text(statementHandle, 4);
598 calendarResult.calendarColour = calendarStream.str();
600 calendarStream.str("");
601 calendarStream << sqlite3_column_text(statementHandle, 5);
602 calendarResult.calendarDescription = calendarStream.str();
604 calendarResult.calendarID = sqlite3_column_int(statementHandle, 0);
605 calendarResult.accountID = sqlite3_column_int(statementHandle, 1);
606 calendarResult.calendarInfoResult = CDSCALENDAR_OK;
607 return calendarResult;
611 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
612 return calendarResult;
616 return calendarResult;
620 CDSGetCalendarInfo CalendarDataStorage::GetCalendar(int calendarID)
623 CDSGetCalendarInfo calendarResult;
624 sqlite3_stmt *statementHandle;
625 sqlite3_stmt *accountHandle;
628 // Check if the calendar exists.
630 resultCode = sqlite3_prepare_v2(db, "SELECT id, accountid, name, calendarid, colour, description FROM calendars WHERE id=(?1);", -1, &statementHandle, nullptr);
632 if (resultCode != 0){
633 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
634 return calendarResult;
637 resultCode = sqlite3_bind_int(statementHandle, 1, calendarID);
639 if (resultCode != 0){
640 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
641 return calendarResult;
644 resultCode = sqlite3_step(statementHandle);
646 if (resultCode == SQLITE_DONE){
648 calendarResult.calendarInfoResult = CDSCALENDAR_NOCALENDAR;
649 return calendarResult;
651 } else if (resultCode == SQLITE_ROW){
653 // Get the calendar data.
655 stringstream calendarStream;
657 calendarStream << sqlite3_column_text(statementHandle, 2);
658 calendarResult.calendarName = calendarStream.str();
660 calendarStream.str("");
661 calendarStream << sqlite3_column_text(statementHandle, 3);
662 calendarResult.calendarTextID = calendarStream.str();
664 calendarStream.str("");
665 calendarStream << sqlite3_column_text(statementHandle, 4);
666 calendarResult.calendarColour = calendarStream.str();
668 calendarStream.str("");
669 calendarStream << sqlite3_column_text(statementHandle, 5);
670 calendarResult.calendarDescription = calendarStream.str();
672 calendarResult.calendarID = sqlite3_column_int(statementHandle, 0);
673 calendarResult.accountID = sqlite3_column_int(statementHandle, 1);
675 // Get the account name.
677 resultCode = sqlite3_prepare_v2(db, "SELECT name FROM accounts WHERE id=(?1);", -1, &accountHandle, nullptr);
679 if (resultCode != 0){
680 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
681 return calendarResult;
684 resultCode = sqlite3_bind_int(accountHandle, 1, calendarResult.accountID);
686 if (resultCode != 0){
687 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
688 return calendarResult;
691 resultCode = sqlite3_step(accountHandle);
693 if (resultCode == SQLITE_ROW){
695 stringstream accountStream;
696 accountStream << sqlite3_column_text(accountHandle, 0);
697 calendarResult.accountName = accountStream.str();
698 calendarResult.accountInfoResult = CDSACCOUNT_OK;
702 calendarResult.accountInfoResult = CDSACCOUNT_FAILED;
706 calendarResult.calendarInfoResult = CDSCALENDAR_OK;
707 return calendarResult;
711 calendarResult.calendarInfoResult = CDSCALENDAR_FAILED;
712 return calendarResult;
716 return calendarResult;
721 CDSCalendarResult CalendarDataStorage::UpdateCalendar(int calendarID, string calendarName, Colour calendarColour, std::string calendarDescription)
724 CDSCalendarResult updateResult = CDSCALENDAR_UNITTESTFAIL;
727 sqlite3_stmt *findHandle;
728 sqlite3_stmt *statementHandle;
730 // Check if calendar exists first.
732 resultCode = sqlite3_prepare_v2(db, "SELECT id from calendars WHERE id=(?1);", -1, &findHandle, nullptr);
734 if (resultCode != 0){
735 return CDSCALENDAR_FAILED;
738 resultCode = sqlite3_bind_int(findHandle, 1, calendarID);
740 if (resultCode != 0){
741 return CDSCALENDAR_FAILED;
744 resultCode = sqlite3_step(findHandle);
746 if (resultCode == SQLITE_ROW){
748 } else if (resultCode == SQLITE_DONE) {
749 return CDSCALENDAR_NOCALENDAR;
751 return CDSCALENDAR_FAILED;
754 // Update the account.
756 resultCode = sqlite3_prepare_v2(db, "UPDATE calendars SET name=(?1), colour=(?2), description=(?3) WHERE id=(?4);", -1, &statementHandle, nullptr);
758 if (resultCode != 0){
759 return CDSCALENDAR_FAILED;
762 resultCode = sqlite3_bind_text(statementHandle, 1, calendarName.c_str(), -1, SQLITE_STATIC);
764 if (resultCode != 0){
765 return CDSCALENDAR_FAILED;
768 resultCode = sqlite3_bind_text(statementHandle, 2, string(calendarColour).c_str(), -1, SQLITE_STATIC);
770 if (resultCode != 0){
771 return CDSCALENDAR_FAILED;
774 resultCode = sqlite3_bind_text(statementHandle, 3, calendarDescription.c_str(), -1, SQLITE_STATIC);
776 if (resultCode != 0){
777 return CDSCALENDAR_FAILED;
780 resultCode = sqlite3_bind_int(statementHandle, 4, calendarID);
782 if (resultCode != 0){
783 return CDSCALENDAR_FAILED;
786 resultCode = sqlite3_step(statementHandle);
788 if (resultCode != SQLITE_DONE){
789 return CDSCALENDAR_FAILED;
792 // Update the checksum.
794 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
796 updateResult = CDSCALENDAR_OK;
802 CDSCalendarResult CalendarDataStorage::DeleteCalendar(int calendarID)
805 CDSCalendarResult deleteResult = CDSCALENDAR_UNITTESTFAIL;
807 // Check if account exists first.
809 sqlite3_stmt *findHandle;
810 sqlite3_stmt *statementHandle;
811 sqlite3_stmt *entriesHandle;
814 resultCode = sqlite3_prepare_v2(db, "SELECT id from calendars WHERE id=(?1);", -1, &findHandle, nullptr);
816 if (resultCode != 0){
817 return CDSCALENDAR_FAILED;
820 resultCode = sqlite3_bind_int(findHandle, 1, calendarID);
822 if (resultCode != 0){
823 return CDSCALENDAR_FAILED;
826 resultCode = sqlite3_step(findHandle);
828 if (resultCode == SQLITE_ROW){
830 } else if (resultCode == SQLITE_DONE) {
831 return CDSCALENDAR_NOCALENDAR;
833 return CDSCALENDAR_FAILED;
836 // Delete the calendar.
838 resultCode = sqlite3_prepare_v2(db, "DELETE FROM calendars WHERE id=(?1);", -1, &statementHandle, nullptr);
840 if (resultCode != 0){
841 return CDSCALENDAR_FAILED;
844 resultCode = sqlite3_bind_int(statementHandle, 1, calendarID);
846 if (resultCode != 0){
847 return CDSCALENDAR_FAILED;
850 resultCode = sqlite3_step(statementHandle);
852 if (resultCode != SQLITE_DONE){
853 return CDSCALENDAR_FAILED;
856 // Delete the calendar entries.
858 resultCode = sqlite3_prepare_v2(db, "DELETE FROM calendarentries WHERE calendarid=(?1);", -1, &entriesHandle, nullptr);
860 if (resultCode != 0){
861 return CDSCALENDAR_FAILED;
864 resultCode = sqlite3_bind_int(entriesHandle, 1, calendarID);
866 if (resultCode != 0){
867 return CDSCALENDAR_FAILED;
870 resultCode = sqlite3_step(entriesHandle);
872 if (resultCode == SQLITE_DONE){
873 deleteResult = CDSCALENDAR_OK;
875 return CDSCALENDAR_FAILED;
878 // Update the checksum.
880 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
886 CDSAddEntryResult CalendarDataStorage::AddEvent(int calendarID, std::string filename)
889 CDSAddEntryResult addResult;
890 addResult.addEventResult = CDSENTRY_UNITTESTFAIL;
892 // Load the event file.
894 CalendarEventObject eventData;
895 CalendarObjectLoadResult eventLoadResult = eventData.LoadFile(filename);
897 // Check the result of the event file load.
899 switch (eventLoadResult){
901 case CALENDAROBJECTLOAD_OK:
903 case CALENDAROBJECTLOAD_MISSING:
904 addResult.addEventResult = CDSENTRY_MISSINGFILE;
906 case CALENDAROBJECTLOAD_INVALIDFORMAT:
907 addResult.addEventResult = CDSENTRY_INVALIDFILE;
909 case CALENDAROBJECTLOAD_CANNOTOPEN:
910 addResult.addEventResult = CDSENTRY_CANNOTOPENFILE;
915 // Check if calendar exists first.
919 sqlite3_stmt *findHandle;
920 sqlite3_stmt *statementHandle;
922 resultCode = sqlite3_prepare_v2(db, "SELECT id from calendars WHERE id=(?1);", -1, &findHandle, nullptr);
924 if (resultCode != 0){
925 addResult.addEventResult = CDSENTRY_FAILED;
929 resultCode = sqlite3_bind_int(findHandle, 1, calendarID);
931 if (resultCode != 0){
932 addResult.addEventResult = CDSENTRY_FAILED;
936 resultCode = sqlite3_step(findHandle);
938 if (resultCode == SQLITE_ROW){
940 } else if (resultCode == SQLITE_DONE) {
941 addResult.addEventResult = CDSENTRY_NOCALENDAR;
944 addResult.addEventResult = CDSENTRY_FAILED;
948 // Get the required values from the event object.
950 int eventStartYear = 0;
951 int eventStartMonth = 0;
952 int eventStartDay = 0;
953 int eventStartHour = 0;
954 int eventStartMinute = 0;
955 int eventStartSecond = 0;
956 int eventStartDuration = 0;
957 std::string eventString = "";
961 if (eventData.DateTimeStartData.size() < 16){
963 addResult.addEventResult = CDSENTRY_INVALIDFILE;
968 eventString = eventData.DateTimeStartData.substr(0,4);
970 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
972 eventStartYear = atoi(eventString.c_str());
976 addResult.addEventResult = CDSENTRY_INVALIDFILE;
981 eventString = eventData.DateTimeStartData.substr(4,2);
983 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
985 eventStartMonth = atoi(eventString.c_str());
989 addResult.addEventResult = CDSENTRY_INVALIDFILE;
994 eventString = eventData.DateTimeStartData.substr(6,2);
996 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
998 eventStartDay = atoi(eventString.c_str());
1002 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1007 eventString = eventData.DateTimeStartData.substr(9,2);
1009 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1011 eventStartHour = atoi(eventString.c_str());
1015 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1020 eventString = eventData.DateTimeStartData.substr(11,2);
1022 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1024 eventStartMinute = atoi(eventString.c_str());
1028 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1033 eventString = eventData.DateTimeStartData.substr(13,2);
1035 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1037 eventStartSecond = atoi(eventString.c_str());
1041 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1046 //eventYear = eventStartDate.substr(0, 4);
1050 int eventEndYear = 0;
1051 int eventEndMonth = 0;
1052 int eventEndDay = 0;
1053 int eventEndHour = 0;
1054 int eventEndMinute = 0;
1055 int eventEndSecond = 0;
1056 int eventEndDuration = 0;
1058 if (eventData.DateTimeEndData != ""){
1060 if (eventData.DateTimeEndData.size() < 16){
1062 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1067 eventString = eventData.DateTimeEndData.substr(0,4);
1069 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1071 eventEndYear = atoi(eventString.c_str());
1075 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1080 eventString = eventData.DateTimeEndData.substr(4,2);
1082 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1084 eventEndMonth = atoi(eventString.c_str());
1088 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1093 eventString = eventData.DateTimeEndData.substr(6,2);
1095 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1097 eventEndDay = atoi(eventString.c_str());
1101 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1106 eventString = eventData.DateTimeEndData.substr(9,2);
1108 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1110 eventEndHour = atoi(eventString.c_str());
1114 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1119 eventString = eventData.DateTimeEndData.substr(11,2);
1121 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1123 eventEndMinute = atoi(eventString.c_str());
1127 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1132 eventString = eventData.DateTimeEndData.substr(13,2);
1134 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1136 eventEndSecond = atoi(eventString.c_str());
1140 addResult.addEventResult = CDSENTRY_INVALIDFILE;
1147 eventString = eventData.DurationData;
1149 // Process the duration data.
1151 int eventDurationWeeks = 0;
1152 int eventDurationDays = 0;
1153 int eventDurationHours = 0;
1154 int eventDurationMinutes = 0;
1155 int eventDurationSeconds = 0;
1157 // Get the duration (if DTEND hasn't been specified).
1159 if (eventData.DurationData.size() > 0){
1161 bool FoundP = false;
1162 bool FoundW = false;
1163 bool DateTimeMode = false;
1165 std::string::iterator eventDataChar = eventData.DurationData.begin();
1166 std::string currentValue = "";
1168 if (*eventDataChar != 'P'){
1170 eventDataChar = eventData.DurationData.end();
1174 for(eventDataChar; eventDataChar != eventData.DurationData.end(); eventDataChar++){
1176 // Check if value is a digit.
1178 if (isdigit(*eventDataChar)){
1180 currentValue += *eventDataChar;
1184 // Check that the value matches one of the letters.
1186 if (*eventDataChar == 'W' && DateTimeMode == false){
1188 eventDurationWeeks = atoi(currentValue.c_str());
1190 } else if (*eventDataChar == 'D' && DateTimeMode == false){
1192 eventDurationDays = atoi(currentValue.c_str());
1194 } else if (*eventDataChar == 'T' && DateTimeMode == false){
1196 DateTimeMode = true;
1198 } else if (*eventDataChar == 'H'){
1200 eventDurationHours = atoi(currentValue.c_str());
1202 } else if (*eventDataChar == 'M'){
1204 eventDurationMinutes = atoi(currentValue.c_str());
1206 } else if (*eventDataChar == 'S'){
1208 eventDurationSeconds = atoi(currentValue.c_str());
1212 // Reset the current value.
1222 // Add the calendar entry.
1224 std::string sqlParameter = "INSERT INTO calendarentries (calendarid, entryname, entrydescription,"
1225 " entrystartyear, entrystartmonth, entrystartday, entrystarthour, entrystartminute, entrystartsecond,"
1226 " entryendyear, entryendmonth, entryendday, entryendhour, entryendminute, entryendsecond, "
1227 " entrydurationweek, entrydurationday, entrydurationhour, entrydurationminute, entrydurationsecond, "
1229 " VALUES ((?1), (?2), (?3), (?4), (?5), (?6), (?7), (?8), (?9), (?10), "
1230 " (?11), (?12), (?13), (?14), (?15), (?16), (?17), (?18), (?19), (?20), (?21))";
1232 resultCode = sqlite3_prepare_v2(db, sqlParameter.c_str(), -1, &statementHandle, nullptr);
1234 resultCode = sqlite3_bind_int(statementHandle, 1, calendarID);
1236 if (resultCode != 0){
1237 addResult.addEventResult = CDSENTRY_FAILED;
1241 // Process Entry Name.
1243 resultCode = sqlite3_bind_text(statementHandle, 2, eventData.SummaryData.c_str(), -1, SQLITE_STATIC);
1245 if (resultCode != 0){
1246 addResult.addEventResult = CDSENTRY_FAILED;
1250 // Process Entry Description.
1252 string eventDescription;
1255 eventDescription = eventData.DescriptionList.at(0);
1258 catch (out_of_range &err){
1259 eventDescription = "";
1262 resultCode = sqlite3_bind_text(statementHandle, 3, eventDescription.c_str(), -1, SQLITE_STATIC);
1264 if (resultCode != 0){
1265 addResult.addEventResult = CDSENTRY_FAILED;
1269 // Process Entry Start Date information.
1271 resultCode = sqlite3_bind_int(statementHandle, 4, eventStartYear);
1273 if (resultCode != 0){
1274 addResult.addEventResult = CDSENTRY_FAILED;
1278 resultCode = sqlite3_bind_int(statementHandle, 5, eventStartMonth);
1280 if (resultCode != 0){
1281 addResult.addEventResult = CDSENTRY_FAILED;
1285 resultCode = sqlite3_bind_int(statementHandle, 6, eventStartDay);
1287 if (resultCode != 0){
1288 addResult.addEventResult = CDSENTRY_FAILED;
1292 resultCode = sqlite3_bind_int(statementHandle, 7, eventStartHour);
1294 if (resultCode != 0){
1295 addResult.addEventResult = CDSENTRY_FAILED;
1299 resultCode = sqlite3_bind_int(statementHandle, 8, eventStartMinute);
1301 if (resultCode != 0){
1302 addResult.addEventResult = CDSENTRY_FAILED;
1306 resultCode = sqlite3_bind_int(statementHandle, 9, eventStartSecond);
1308 if (resultCode != 0){
1309 addResult.addEventResult = CDSENTRY_FAILED;
1313 // Process Entry Start End information.
1315 resultCode = sqlite3_bind_int(statementHandle, 10, eventEndYear);
1317 if (resultCode != 0){
1318 addResult.addEventResult = CDSENTRY_FAILED;
1322 resultCode = sqlite3_bind_int(statementHandle, 11, eventEndMonth);
1324 if (resultCode != 0){
1325 addResult.addEventResult = CDSENTRY_FAILED;
1329 resultCode = sqlite3_bind_int(statementHandle, 12, eventEndDay);
1331 if (resultCode != 0){
1332 addResult.addEventResult = CDSENTRY_FAILED;
1336 resultCode = sqlite3_bind_int(statementHandle, 13, eventEndHour);
1338 if (resultCode != 0){
1339 addResult.addEventResult = CDSENTRY_FAILED;
1343 resultCode = sqlite3_bind_int(statementHandle, 14, eventEndMinute);
1345 if (resultCode != 0){
1346 addResult.addEventResult = CDSENTRY_FAILED;
1350 resultCode = sqlite3_bind_int(statementHandle, 15, eventEndSecond);
1352 if (resultCode != 0){
1353 addResult.addEventResult = CDSENTRY_FAILED;
1357 resultCode = sqlite3_bind_int(statementHandle, 16, eventDurationWeeks);
1359 if (resultCode != 0){
1360 addResult.addEventResult = CDSENTRY_FAILED;
1364 resultCode = sqlite3_bind_int(statementHandle, 17, eventDurationDays);
1366 if (resultCode != 0){
1367 addResult.addEventResult = CDSENTRY_FAILED;
1371 resultCode = sqlite3_bind_int(statementHandle, 18, eventDurationHours);
1373 if (resultCode != 0){
1374 addResult.addEventResult = CDSENTRY_FAILED;
1378 resultCode = sqlite3_bind_int(statementHandle, 19, eventDurationMinutes);
1380 if (resultCode != 0){
1381 addResult.addEventResult = CDSENTRY_FAILED;
1385 resultCode = sqlite3_bind_int(statementHandle, 20, eventDurationSeconds);
1387 if (resultCode != 0){
1388 addResult.addEventResult = CDSENTRY_FAILED;
1392 resultCode = sqlite3_bind_text(statementHandle, 21, filename.c_str(), -1, SQLITE_STATIC);
1394 if (resultCode != 0){
1395 addResult.addEventResult = CDSENTRY_FAILED;
1399 resultCode = sqlite3_step(statementHandle);
1401 if (resultCode != SQLITE_DONE){
1402 addResult.addEventResult = CDSENTRY_FAILED;
1406 addResult.calendarEntryID = sqlite3_last_insert_rowid(db);
1407 addResult.addEventResult = CDSENTRY_OK;
1409 // Update the checksum.
1411 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
1417 CDSEditEntryResult CalendarDataStorage::UpdateEvent(int eventID, std::string filename)
1420 CDSEditEntryResult editResult;
1421 editResult.editEventResult = CDSENTRY_UNITTESTFAIL;
1423 // Load the event file.
1425 CalendarEventObject eventData;
1426 CalendarObjectLoadResult eventLoadResult = eventData.LoadFile(filename);
1428 // Check the result of the event file load.
1430 switch (eventLoadResult){
1432 case CALENDAROBJECTLOAD_OK:
1434 case CALENDAROBJECTLOAD_MISSING:
1435 editResult.editEventResult = CDSENTRY_MISSINGFILE;
1437 case CALENDAROBJECTLOAD_INVALIDFORMAT:
1438 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1440 case CALENDAROBJECTLOAD_CANNOTOPEN:
1441 editResult.editEventResult = CDSENTRY_CANNOTOPENFILE;
1446 // Check if event exists first.
1450 sqlite3_stmt *findHandle;
1451 sqlite3_stmt *statementHandle;
1453 resultCode = sqlite3_prepare_v2(db, "SELECT id from calendarentries WHERE id=(?1);", -1, &findHandle, nullptr);
1455 if (resultCode != 0){
1456 editResult.editEventResult = CDSENTRY_FAILED;
1460 resultCode = sqlite3_bind_int(findHandle, 1, eventID);
1462 if (resultCode != 0){
1463 editResult.editEventResult = CDSENTRY_FAILED;
1467 resultCode = sqlite3_step(findHandle);
1469 if (resultCode == SQLITE_ROW){
1471 } else if (resultCode == SQLITE_DONE) {
1472 editResult.editEventResult = CDSENTRY_NOENTRY;
1475 editResult.editEventResult = CDSENTRY_FAILED;
1479 // Get the required values from the event object.
1481 int eventStartYear = 0;
1482 int eventStartMonth = 0;
1483 int eventStartDay = 0;
1484 int eventStartHour = 0;
1485 int eventStartMinute = 0;
1486 int eventStartSecond = 0;
1487 int eventStartDuration = 0;
1488 std::string eventString = "";
1492 if (eventData.DateTimeStartData.size() < 16){
1494 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1499 eventString = eventData.DateTimeStartData.substr(0,4);
1501 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1503 eventStartYear = atoi(eventString.c_str());
1507 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1512 eventString = eventData.DateTimeStartData.substr(4,2);
1514 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1516 eventStartMonth = atoi(eventString.c_str());
1520 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1525 eventString = eventData.DateTimeStartData.substr(6,2);
1527 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1529 eventStartDay = atoi(eventString.c_str());
1533 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1538 eventString = eventData.DateTimeStartData.substr(9,2);
1540 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1542 eventStartHour = atoi(eventString.c_str());
1546 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1551 eventString = eventData.DateTimeStartData.substr(11,2);
1553 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1555 eventStartMinute = atoi(eventString.c_str());
1559 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1564 eventString = eventData.DateTimeStartData.substr(13,2);
1566 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1568 eventStartSecond = atoi(eventString.c_str());
1572 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1577 //eventYear = eventStartDate.substr(0, 4);
1581 int eventEndYear = 0;
1582 int eventEndMonth = 0;
1583 int eventEndDay = 0;
1584 int eventEndHour = 0;
1585 int eventEndMinute = 0;
1586 int eventEndSecond = 0;
1587 int eventEndDuration = 0;
1589 if (eventData.DateTimeEndData != ""){
1591 if (eventData.DateTimeEndData.size() < 16){
1593 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1598 eventString = eventData.DateTimeEndData.substr(0,4);
1600 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1602 eventEndYear = atoi(eventString.c_str());
1606 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1611 eventString = eventData.DateTimeEndData.substr(4,2);
1613 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1615 eventEndMonth = atoi(eventString.c_str());
1619 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1624 eventString = eventData.DateTimeEndData.substr(6,2);
1626 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1628 eventEndDay = atoi(eventString.c_str());
1632 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1637 eventString = eventData.DateTimeEndData.substr(9,2);
1639 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1641 eventEndHour = atoi(eventString.c_str());
1645 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1650 eventString = eventData.DateTimeEndData.substr(11,2);
1652 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1654 eventEndMinute = atoi(eventString.c_str());
1658 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1663 eventString = eventData.DateTimeEndData.substr(13,2);
1665 if (all_of(eventString.begin(), eventString.end(), ::isdigit)){
1667 eventEndSecond = atoi(eventString.c_str());
1671 editResult.editEventResult = CDSENTRY_INVALIDFILE;
1678 eventString = eventData.DurationData;
1680 // Process the duration data.
1682 int eventDurationWeeks = 0;
1683 int eventDurationDays = 0;
1684 int eventDurationHours = 0;
1685 int eventDurationMinutes = 0;
1686 int eventDurationSeconds = 0;
1688 // Get the duration (if DTEND hasn't been specified).
1690 if (eventData.DurationData.size() > 0){
1692 bool FoundP = false;
1693 bool FoundW = false;
1694 bool DateTimeMode = false;
1696 std::string::iterator eventDataChar = eventData.DurationData.begin();
1697 std::string currentValue = "";
1699 if (*eventDataChar != 'P'){
1701 eventDataChar = eventData.DurationData.end();
1705 for(eventDataChar; eventDataChar != eventData.DurationData.end(); eventDataChar++){
1707 // Check if value is a digit.
1709 if (isdigit(*eventDataChar)){
1711 currentValue += *eventDataChar;
1715 // Check that the value matches one of the letters.
1717 if (*eventDataChar == 'W' && DateTimeMode == false){
1719 eventDurationWeeks = atoi(currentValue.c_str());
1721 } else if (*eventDataChar == 'D' && DateTimeMode == false){
1723 eventDurationDays = atoi(currentValue.c_str());
1725 } else if (*eventDataChar == 'T' && DateTimeMode == false){
1727 DateTimeMode = true;
1729 } else if (*eventDataChar == 'H'){
1731 eventDurationHours = atoi(currentValue.c_str());
1733 } else if (*eventDataChar == 'M'){
1735 eventDurationMinutes = atoi(currentValue.c_str());
1737 } else if (*eventDataChar == 'S'){
1739 eventDurationSeconds = atoi(currentValue.c_str());
1743 // Reset the current value.
1753 // Add the calendar entry.
1755 std::string sqlParameter = "UPDATE calendarentries SET entryname=(?2), entrydescription=(?3),"
1756 " entrystartyear=(?4), entrystartmonth=(?5), entrystartday=(?6), entrystarthour=(?7), entrystartminute=(?8), entrystartsecond=(?9),"
1757 " entryendyear=(?10), entryendmonth=(?11), entryendday=(?12), entryendhour=(?13), entryendminute=(?14), entryendsecond=(?15), "
1758 " entrydurationweek=(?16), entrydurationday=(?17), entrydurationhour=(?18), entrydurationminute=(?19), entrydurationsecond=(?20), "
1761 resultCode = sqlite3_prepare_v2(db, sqlParameter.c_str(), -1, &statementHandle, nullptr);
1763 resultCode = sqlite3_bind_int(statementHandle, 1, eventID);
1765 if (resultCode != 0){
1766 editResult.editEventResult = CDSENTRY_FAILED;
1770 // Process Entry Name.
1772 resultCode = sqlite3_bind_text(statementHandle, 2, eventData.SummaryData.c_str(), -1, SQLITE_STATIC);
1774 if (resultCode != 0){
1775 editResult.editEventResult = CDSENTRY_FAILED;
1779 // Process Entry Description.
1781 string eventDescription;
1784 eventDescription = eventData.DescriptionList.at(0);
1787 catch (out_of_range &err){
1788 eventDescription = "";
1791 resultCode = sqlite3_bind_text(statementHandle, 3, eventDescription.c_str(), -1, SQLITE_STATIC);
1793 if (resultCode != 0){
1794 editResult.editEventResult = CDSENTRY_FAILED;
1798 // Process Entry Start Date information.
1800 resultCode = sqlite3_bind_int(statementHandle, 4, eventStartYear);
1802 if (resultCode != 0){
1803 editResult.editEventResult = CDSENTRY_FAILED;
1807 resultCode = sqlite3_bind_int(statementHandle, 5, eventStartMonth);
1809 if (resultCode != 0){
1810 editResult.editEventResult = CDSENTRY_FAILED;
1814 resultCode = sqlite3_bind_int(statementHandle, 6, eventStartDay);
1816 if (resultCode != 0){
1817 editResult.editEventResult = CDSENTRY_FAILED;
1821 resultCode = sqlite3_bind_int(statementHandle, 7, eventStartHour);
1823 if (resultCode != 0){
1824 editResult.editEventResult = CDSENTRY_FAILED;
1828 resultCode = sqlite3_bind_int(statementHandle, 8, eventStartMinute);
1830 if (resultCode != 0){
1831 editResult.editEventResult = CDSENTRY_FAILED;
1835 resultCode = sqlite3_bind_int(statementHandle, 9, eventStartSecond);
1837 if (resultCode != 0){
1838 editResult.editEventResult = CDSENTRY_FAILED;
1842 // Process Entry Start End information.
1844 resultCode = sqlite3_bind_int(statementHandle, 10, eventEndYear);
1846 if (resultCode != 0){
1847 editResult.editEventResult = CDSENTRY_FAILED;
1851 resultCode = sqlite3_bind_int(statementHandle, 11, eventEndMonth);
1853 if (resultCode != 0){
1854 editResult.editEventResult = CDSENTRY_FAILED;
1858 resultCode = sqlite3_bind_int(statementHandle, 12, eventEndDay);
1860 if (resultCode != 0){
1861 editResult.editEventResult = CDSENTRY_FAILED;
1865 resultCode = sqlite3_bind_int(statementHandle, 13, eventEndHour);
1867 if (resultCode != 0){
1868 editResult.editEventResult = CDSENTRY_FAILED;
1872 resultCode = sqlite3_bind_int(statementHandle, 14, eventEndMinute);
1874 if (resultCode != 0){
1875 editResult.editEventResult = CDSENTRY_FAILED;
1879 resultCode = sqlite3_bind_int(statementHandle, 15, eventEndSecond);
1881 if (resultCode != 0){
1882 editResult.editEventResult = CDSENTRY_FAILED;
1886 resultCode = sqlite3_bind_int(statementHandle, 16, eventDurationWeeks);
1888 if (resultCode != 0){
1889 editResult.editEventResult = CDSENTRY_FAILED;
1893 resultCode = sqlite3_bind_int(statementHandle, 17, eventDurationDays);
1895 if (resultCode != 0){
1896 editResult.editEventResult = CDSENTRY_FAILED;
1900 resultCode = sqlite3_bind_int(statementHandle, 18, eventDurationHours);
1902 if (resultCode != 0){
1903 editResult.editEventResult = CDSENTRY_FAILED;
1907 resultCode = sqlite3_bind_int(statementHandle, 19, eventDurationMinutes);
1909 if (resultCode != 0){
1910 editResult.editEventResult = CDSENTRY_FAILED;
1914 resultCode = sqlite3_bind_int(statementHandle, 20, eventDurationSeconds);
1916 if (resultCode != 0){
1917 editResult.editEventResult = CDSENTRY_FAILED;
1921 resultCode = sqlite3_step(statementHandle);
1923 if (resultCode != SQLITE_DONE){
1924 editResult.editEventResult = CDSENTRY_FAILED;
1928 editResult.calendarEntryID = sqlite3_last_insert_rowid(db);
1929 editResult.editEventResult = CDSENTRY_OK;
1931 // Update the checksum.
1933 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
1939 CDSGetCalendarEntryInfo CalendarDataStorage::GetEvent(int calendarEntryID)
1942 CDSGetCalendarEntryInfo entryResult;
1944 // Check if the calendar entry exists.
1948 sqlite3_stmt *findHandle;
1949 sqlite3_stmt *statementHandle;
1951 resultCode = sqlite3_prepare_v2(db, "SELECT id FROM calendarentries WHERE id=(?1);", -1, &findHandle, nullptr);
1953 if (resultCode != 0){
1954 entryResult.getEventResult = CDSENTRY_FAILED;
1958 resultCode = sqlite3_bind_int(findHandle, 1, calendarEntryID);
1960 if (resultCode != 0){
1961 entryResult.getEventResult = CDSENTRY_FAILED;
1965 resultCode = sqlite3_step(findHandle);
1967 if (resultCode == SQLITE_ROW){
1969 } else if (resultCode == SQLITE_DONE) {
1970 entryResult.getEventResult = CDSENTRY_NOENTRY;
1973 entryResult.getEventResult = CDSENTRY_FAILED;
1977 // Get the calendar entry data.
1979 std::string sqlParameter = "SELECT entryname, entrydescription,"
1980 " entrystartyear, entrystartmonth, entrystartday, entrystarthour, entrystartminute, entrystartsecond,"
1981 " entryendyear, entryendmonth, entryendday, entryendhour, entryendminute, entryendsecond, "
1982 " entrydurationweek, entrydurationday, entrydurationhour, entrydurationminute, entrydurationsecond, "
1983 " calendarid, id, filename"
1984 " FROM calendarentries WHERE id=(?1)";
1986 resultCode = sqlite3_prepare_v2(db, sqlParameter.c_str(), -1, &statementHandle, nullptr);
1988 if (resultCode != 0){
1989 entryResult.getEventResult = CDSENTRY_FAILED;
1993 resultCode = sqlite3_bind_int(statementHandle, 1, calendarEntryID);
1995 if (resultCode != 0){
1996 entryResult.getEventResult = CDSENTRY_FAILED;
2000 resultCode = sqlite3_step(statementHandle);
2002 if (resultCode == SQLITE_ROW){
2004 // Get the calendar entry name,
2006 stringstream entryStream;
2008 entryStream << sqlite3_column_text(statementHandle, 0);
2009 entryResult.entryName = entryStream.str();
2011 entryStream.str("");
2013 // Get the calendar entry description.
2015 entryStream << sqlite3_column_text(statementHandle, 1);
2016 entryResult.entryDescription = entryStream.str();
2018 entryStream.str("");
2020 // Get the calendar entry filename.
2022 entryStream << sqlite3_column_text(statementHandle, 21);
2023 entryResult.entryFilename = entryStream.str();
2025 entryStream.str("");
2027 entryResult.entryStartYear = sqlite3_column_int(statementHandle, 2);
2028 entryResult.entryStartMonth = sqlite3_column_int(statementHandle, 3);
2029 entryResult.entryStartDay = sqlite3_column_int(statementHandle, 4);
2030 entryResult.entryStartHour = sqlite3_column_int(statementHandle, 5);
2031 entryResult.entryStartMinute = sqlite3_column_int(statementHandle, 6);
2032 entryResult.entryStartSecond = sqlite3_column_int(statementHandle, 7);
2033 entryResult.entryEndYear = sqlite3_column_int(statementHandle, 8);
2034 entryResult.entryEndMonth = sqlite3_column_int(statementHandle, 9);
2035 entryResult.entryEndDay = sqlite3_column_int(statementHandle, 10);
2036 entryResult.entryEndHour = sqlite3_column_int(statementHandle, 11);
2037 entryResult.entryEndMinute = sqlite3_column_int(statementHandle, 12);
2038 entryResult.entryEndSecond = sqlite3_column_int(statementHandle, 13);
2039 entryResult.entryDurationWeeks = sqlite3_column_int(statementHandle, 14);
2040 entryResult.entryDurationDays = sqlite3_column_int(statementHandle, 15);
2041 entryResult.entryDurationHours = sqlite3_column_int(statementHandle, 16);
2042 entryResult.entryDurationMinutes = sqlite3_column_int(statementHandle, 17);
2043 entryResult.entryDurationSeconds = sqlite3_column_int(statementHandle, 18);
2044 entryResult.calendarID = sqlite3_column_int(statementHandle, 19);
2045 entryResult.calendarEntryID = sqlite3_column_int(statementHandle, 20);
2047 } else if (resultCode == SQLITE_DONE) {
2048 entryResult.getEventResult = CDSENTRY_NOCALENDAR;
2051 entryResult.getEventResult = CDSENTRY_FAILED;
2055 entryResult.getEventResult = CDSENTRY_OK;
2061 CDSEntryResult CalendarDataStorage::DeleteEvent(int calendarEntryID)
2064 CDSEntryResult deleteResult = CDSENTRY_UNITTESTFAIL;
2066 // Check if the calendar entry exists.
2070 sqlite3_stmt *findHandle;
2071 sqlite3_stmt *statementHandle;
2073 resultCode = sqlite3_prepare_v2(db, "SELECT id FROM calendarentries WHERE id=(?1);", -1, &findHandle, nullptr);
2075 if (resultCode != 0){
2076 return CDSENTRY_FAILED;
2079 resultCode = sqlite3_bind_int(findHandle, 1, calendarEntryID);
2081 if (resultCode != 0){
2082 return CDSENTRY_FAILED;
2085 resultCode = sqlite3_step(findHandle);
2087 if (resultCode == SQLITE_ROW){
2089 } else if (resultCode == SQLITE_DONE) {
2090 return CDSENTRY_NOENTRY;
2092 return CDSENTRY_FAILED;
2095 // Delete the account.
2097 resultCode = sqlite3_prepare_v2(db, "DELETE FROM calendarentries WHERE id=(?1);", -1, &statementHandle, nullptr);
2099 if (resultCode != 0){
2100 return CDSENTRY_FAILED;
2103 resultCode = sqlite3_bind_int(statementHandle, 1, calendarEntryID);
2105 if (resultCode != 0){
2106 return CDSENTRY_FAILED;
2109 resultCode = sqlite3_step(statementHandle);
2111 if (resultCode == SQLITE_DONE){
2112 deleteResult = CDSENTRY_OK;
2114 return CDSENTRY_FAILED;
2117 // Update the checksum.
2119 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
2121 return deleteResult;
2125 CDSEntryList CalendarDataStorage::GetEventList(int calendarID){
2127 CDSEntryList entryList;
2128 entryList.getEventListResult = CDSENTRY_UNITTESTFAIL;
2130 // Check if calendar exists first.
2134 sqlite3_stmt *findHandle;
2135 sqlite3_stmt *calendarHandle;
2137 resultCode = sqlite3_prepare_v2(db, "SELECT id from calendars WHERE id=(?1);", -1, &findHandle, nullptr);
2139 if (resultCode != 0){
2140 entryList.getEventListResult = CDSENTRY_FAILED;
2144 resultCode = sqlite3_bind_int(findHandle, 1, calendarID);
2146 if (resultCode != 0){
2147 entryList.getEventListResult = CDSENTRY_FAILED;
2151 resultCode = sqlite3_step(findHandle);
2153 if (resultCode == SQLITE_ROW){
2155 } else if (resultCode == SQLITE_DONE) {
2156 entryList.getEventListResult = CDSENTRY_NOCALENDAR;
2159 entryList.getEventListResult = CDSENTRY_FAILED;
2163 // Get the list of entry IDs.
2165 resultCode = sqlite3_prepare_v2(db, "SELECT id FROM calendarentries WHERE calendarid=(?1);", -1, &calendarHandle, nullptr);
2167 if (resultCode != 0){
2168 entryList.getEventListResult = CDSENTRY_FAILED;
2172 resultCode = sqlite3_bind_int(calendarHandle, 1, calendarID);
2174 if (resultCode != 0){
2175 entryList.getEventListResult = CDSENTRY_FAILED;
2179 resultCode = sqlite3_step(calendarHandle);
2181 if (resultCode == SQLITE_DONE || resultCode == SQLITE_ROW){
2183 entryList.getEventListResult = CDSENTRY_FAILED;
2187 while (resultCode == SQLITE_ROW){
2189 int calendarID = sqlite3_column_int(calendarHandle, 0);
2191 entryList.entryList.push_back(calendarID);
2193 resultCode = sqlite3_step(calendarHandle);
2197 entryList.getEventListResult = CDSENTRY_OK;
2203 CDSEntryList CalendarDataStorage::GetEventListByDate(int calendarYear, int calendarMonth, int calendarDay){
2205 CDSEntryList entryList;
2206 entryList.getEventListResult = CDSENTRY_UNITTESTFAIL;
2208 // Check if calendar exists first.
2212 sqlite3_stmt *calendarHandle;
2214 // Get the list of entry IDs.
2216 resultCode = sqlite3_prepare_v2(db, "SELECT id FROM calendarentries WHERE entrystartyear=(?1) AND entrystartmonth=(?2) AND entrystartday=(?3);", -1, &calendarHandle, nullptr);
2218 if (resultCode != 0){
2219 entryList.getEventListResult = CDSENTRY_FAILED;
2223 resultCode = sqlite3_bind_int(calendarHandle, 1, calendarYear);
2225 if (resultCode != 0){
2226 entryList.getEventListResult = CDSENTRY_FAILED;
2230 resultCode = sqlite3_bind_int(calendarHandle, 2, calendarMonth);
2232 if (resultCode != 0){
2233 entryList.getEventListResult = CDSENTRY_FAILED;
2237 resultCode = sqlite3_bind_int(calendarHandle, 3, calendarDay);
2239 if (resultCode != 0){
2240 entryList.getEventListResult = CDSENTRY_FAILED;
2244 resultCode = sqlite3_step(calendarHandle);
2246 if (resultCode == SQLITE_DONE || resultCode == SQLITE_ROW){
2248 entryList.getEventListResult = CDSENTRY_FAILED;
2252 while (resultCode == SQLITE_ROW){
2254 int calendarID = sqlite3_column_int(calendarHandle, 0);
2256 entryList.entryList.push_back(calendarID);
2258 resultCode = sqlite3_step(calendarHandle);
2262 entryList.getEventListResult = CDSENTRY_OK;
2268 CDSCalendarList CalendarDataStorage::GetCalendarList(int accountID){
2270 CDSCalendarList calendarList;
2271 calendarList.getCalendarListResult = CDSCALENDAR_UNITTESTFAIL;
2273 // Check if calendar exists first.
2277 sqlite3_stmt *findHandle;
2278 sqlite3_stmt *calendarHandle;
2280 resultCode = sqlite3_prepare_v2(db, "SELECT id from accounts WHERE id=(?1);", -1, &findHandle, nullptr);
2282 if (resultCode != 0){
2283 calendarList.getCalendarListResult = CDSCALENDAR_FAILED;
2284 return calendarList;
2287 resultCode = sqlite3_bind_int(findHandle, 1, accountID);
2289 if (resultCode != 0){
2290 calendarList.getCalendarListResult = CDSCALENDAR_FAILED;
2291 return calendarList;
2294 resultCode = sqlite3_step(findHandle);
2296 if (resultCode == SQLITE_ROW){
2298 } else if (resultCode == SQLITE_DONE) {
2299 calendarList.getCalendarListResult = CDSCALENDAR_NOCALENDAR;
2300 return calendarList;
2302 calendarList.getCalendarListResult = CDSCALENDAR_FAILED;
2303 return calendarList;
2306 // Get the list of entry IDs.
2308 resultCode = sqlite3_prepare_v2(db, "SELECT id, calendarid FROM calendars WHERE accountid=(?1);", -1, &calendarHandle, nullptr);
2310 if (resultCode != 0){
2311 calendarList.getCalendarListResult = CDSCALENDAR_FAILED;
2312 return calendarList;
2315 resultCode = sqlite3_bind_int(calendarHandle, 1, accountID);
2317 if (resultCode != 0){
2318 calendarList.getCalendarListResult = CDSCALENDAR_FAILED;
2319 return calendarList;
2322 resultCode = sqlite3_step(calendarHandle);
2324 if (resultCode == SQLITE_DONE || resultCode == SQLITE_ROW){
2326 calendarList.getCalendarListResult = CDSCALENDAR_FAILED;
2327 return calendarList;
2330 while (resultCode == SQLITE_ROW){
2332 int calendarID = sqlite3_column_int(calendarHandle, 0);
2334 stringstream calendarStream;
2336 calendarStream << sqlite3_column_text(calendarHandle, 1);
2338 calendarList.calendarList.push_back(calendarID);
2339 calendarList.calendarListTextID.push_back(calendarStream.str());
2341 calendarStream.str("");
2343 resultCode = sqlite3_step(calendarHandle);
2347 calendarList.getCalendarListResult = CDSCALENDAR_OK;
2349 return calendarList;
2353 CDSChecksumResult CalendarDataStorage::AddChecksum(string checksumName, string checksumValue){
2357 // Check if the checksum already exists.
2359 sqlite3_stmt *findHandle;
2360 sqlite3_stmt *checksumHandle;
2362 resultCode = sqlite3_prepare_v2(db, "SELECT checksumvalue from checksums WHERE checksumname=(?1);", -1, &findHandle, nullptr);
2364 if (resultCode != 0){
2365 return CDSCHECKSUM_FAILED;
2368 resultCode = sqlite3_bind_text(findHandle, 1, checksumName.c_str(), -1, SQLITE_STATIC);
2370 if (resultCode != 0){
2371 return CDSCHECKSUM_FAILED;
2374 resultCode = sqlite3_step(findHandle);
2376 if (resultCode == SQLITE_ROW){
2377 return CDSCHECKSUM_CHECKSUMALREADYEXISTS;
2378 } else if (resultCode == SQLITE_DONE) {
2381 return CDSCHECKSUM_FAILED;
2384 // Add the checksum to the checksum table.
2386 resultCode = sqlite3_prepare_v2(db, "INSERT INTO checksums (checksumname, checksumvalue) VALUES(?1, ?2);", -1, &checksumHandle, nullptr);
2388 if (resultCode != 0){
2389 return CDSCHECKSUM_FAILED;
2392 resultCode = sqlite3_bind_text(checksumHandle, 1, checksumName.c_str(), -1, SQLITE_STATIC);
2394 if (resultCode != 0){
2395 return CDSCHECKSUM_FAILED;
2398 resultCode = sqlite3_bind_text(checksumHandle, 2, checksumValue.c_str(), -1, SQLITE_STATIC);
2400 if (resultCode != 0){
2401 return CDSCHECKSUM_FAILED;
2404 resultCode = sqlite3_step(checksumHandle);
2406 if (resultCode != SQLITE_DONE){
2407 return CDSCHECKSUM_FAILED;
2410 return CDSCHECKSUM_OK;
2414 CDSGetChecksumResult CalendarDataStorage::GetChecksum(string checksumName){
2416 CDSGetChecksumResult getChecksumResult;
2420 // Check if the checksum already exists.
2422 sqlite3_stmt *getHandle;
2424 resultCode = sqlite3_prepare_v2(db, "SELECT checksumvalue from checksums WHERE checksumname=(?1);", -1, &getHandle, nullptr);
2426 if (resultCode != 0){
2427 getChecksumResult.getChecksumResult = CDSCHECKSUM_FAILED;
2428 return getChecksumResult;
2431 resultCode = sqlite3_bind_text(getHandle, 1, checksumName.c_str(), -1, SQLITE_STATIC);
2433 if (resultCode != 0){
2434 getChecksumResult.getChecksumResult = CDSCHECKSUM_FAILED;
2435 return getChecksumResult;
2438 resultCode = sqlite3_step(getHandle);
2440 if (resultCode == SQLITE_ROW){
2441 } else if (resultCode == SQLITE_DONE) {
2442 getChecksumResult.getChecksumResult = CDSCHECKSUM_NOHASH;
2443 return getChecksumResult;
2445 getChecksumResult.getChecksumResult = CDSCHECKSUM_FAILED;
2446 return getChecksumResult;
2449 stringstream checksumStream;
2451 checksumStream << sqlite3_column_text(getHandle, 0);
2453 getChecksumResult.checksumValue = checksumStream.str();
2455 getChecksumResult.getChecksumResult = CDSCHECKSUM_OK;
2457 return getChecksumResult;
2461 CDSChecksumResult CalendarDataStorage::UpdateChecksum(std::string checksumName, std::string checksumValue){
2465 // Check if the checksum already exists.
2467 sqlite3_stmt *getHandle;
2468 sqlite3_stmt *statementHandle;
2470 resultCode = sqlite3_prepare_v2(db, "SELECT checksumvalue from checksums WHERE checksumname=(?1);", -1, &getHandle, nullptr);
2472 if (resultCode != 0){
2473 return CDSCHECKSUM_FAILED;
2476 resultCode = sqlite3_bind_text(getHandle, 1, checksumName.c_str(), -1, SQLITE_STATIC);
2478 if (resultCode != 0){
2479 return CDSCHECKSUM_FAILED;
2482 resultCode = sqlite3_step(getHandle);
2484 if (resultCode == SQLITE_ROW){
2485 } else if (resultCode == SQLITE_DONE) {
2486 return CDSCHECKSUM_NOHASH;
2488 return CDSCHECKSUM_FAILED;
2491 // Update the checksum.
2493 resultCode = sqlite3_prepare_v2(db, "UPDATE checksums SET checksumvalue=(?1) WHERE checksumname=(?2);", -1, &statementHandle, nullptr);
2495 if (resultCode != 0){
2496 return CDSCHECKSUM_FAILED;
2499 resultCode = sqlite3_bind_text(statementHandle, 1, checksumValue.c_str(), -1, SQLITE_STATIC);
2501 if (resultCode != 0){
2502 return CDSCHECKSUM_FAILED;
2505 resultCode = sqlite3_bind_text(statementHandle, 2, checksumName.c_str(), -1, SQLITE_STATIC);
2507 if (resultCode != 0){
2508 return CDSCHECKSUM_FAILED;
2511 resultCode = sqlite3_step(statementHandle);
2513 if (resultCode != SQLITE_DONE){
2514 return CDSCHECKSUM_FAILED;
2517 return CDSCHECKSUM_OK;
2521 CDSCleanupResult CalendarDataStorage::Clear(){
2523 // Remove all data from the tables and reset the sequence numbers.
2526 sqlite3_stmt *statementHandle;
2528 resultCode = sqlite3_prepare_v2(db, "DELETE FROM calendarentries", - 1, &statementHandle, nullptr);
2530 if (resultCode != 0){
2531 cout << "Fail 1" << endl;
2532 return CDSCLEANUP_FAILED;
2535 resultCode = sqlite3_step(statementHandle);
2537 if (resultCode != SQLITE_DONE){
2538 cout << "Fail 2" << endl;
2539 return CDSCLEANUP_FAILED;
2542 resultCode = sqlite3_prepare_v2(db, "DELETE FROM sqlite_sequence WHERE name='calendarentries';", -1, &statementHandle, nullptr);
2544 if (resultCode != 0){
2545 cout << "Fail 3" << endl;
2546 cout << sqlite3_errmsg(db) << endl;
2547 return CDSCLEANUP_FAILED;
2550 resultCode = sqlite3_step(statementHandle);
2552 if (resultCode != SQLITE_DONE){
2553 cout << "Fail 4" << endl;
2554 return CDSCLEANUP_FAILED;
2557 resultCode = sqlite3_prepare_v2(db, "DELETE FROM calendars", -1, &statementHandle, nullptr);
2559 if (resultCode != 0){
2560 cout << "Fail 5" << endl;
2561 return CDSCLEANUP_FAILED;
2564 resultCode = sqlite3_step(statementHandle);
2566 if (resultCode != SQLITE_DONE){
2567 cout << "Fail 6" << endl;
2568 return CDSCLEANUP_FAILED;
2571 resultCode = sqlite3_prepare_v2(db, "DELETE FROM sqlite_sequence WHERE name='calendars';", -1, &statementHandle, nullptr);
2573 if (resultCode != 0){
2574 cout << "Fail 7" << endl;
2575 return CDSCLEANUP_FAILED;
2578 resultCode = sqlite3_step(statementHandle);
2580 if (resultCode != SQLITE_DONE){
2581 cout << "Fail 8" << endl;
2582 return CDSCLEANUP_FAILED;
2585 resultCode = sqlite3_prepare_v2(db, "DELETE FROM accounts", -1, &statementHandle, nullptr);
2587 if (resultCode != 0){
2588 cout << "Fail 9" << endl;
2589 return CDSCLEANUP_FAILED;
2592 resultCode = sqlite3_step(statementHandle);
2594 if (resultCode != SQLITE_DONE){
2595 cout << "Fail 10" << endl;
2596 return CDSCLEANUP_FAILED;
2599 resultCode = sqlite3_prepare_v2(db, "DELETE FROM sqlite_sequence WHERE name='accounts'", -1, &statementHandle, nullptr);
2601 if (resultCode != 0){
2602 cout << "Fail 11" << endl;
2603 return CDSCLEANUP_FAILED;
2606 resultCode = sqlite3_step(statementHandle);
2608 if (resultCode != SQLITE_DONE){
2609 cout << "Fail 12" << endl;
2610 return CDSCLEANUP_FAILED;
2613 // Update the checksum.
2615 UpdateChecksum("internal_updatedata", to_string(GenerateRandomNumber(CDS_RANDOMPOW)));
2617 return CDSCLEANUP_OK;