As a workaround, I did the following (requires development mode and the sqlite3 package):
I never worked on the calendar software, so I hope this does not mess things up seriously. Follow these steps at your own risk and make a backup!
-
Remove and readd your exchange account
-
Open a terminal on your phone (or better, SSH into it, because it is easier done on a computer) and run sqlite3 to edit the calendar database as root:
$ devel-su sqlite3 ~/.local/share/system/privileged/Calendar/mkcal/db
-
You are now in a sqlite3 shell. Let’s backup the database first, so you can roll back if you mess up
sqlite> .backup calendar.db.bak
-
Change the output mode to something more human readable
sqlite> .mode table
-
Find the id of the old account from the
Calendars
table. The following query will find accounts that have multiple calendars with the same name:sqlite> SELECT Name, account, pluginName, COUNT(*) as cal_count FROM Calendars GROUP BY Name, account, pluginName HAVING cal_count > 1; +-------------------------+---------+---------------------+-----------+ | Name | account | pluginName | cal_count | +-------------------------+---------+---------------------+-----------+ | Agenda | 16 | EasInvitationPlugin | 37 | | Feestdagen in Nederland | 16 | EasInvitationPlugin | 37 | | Verjaardagen | 16 | EasInvitationPlugin | 37 | +-------------------------+---------+---------------------+-----------+
In my case, the id is
16
. -
Danger zone: at this point, make sure you have made a backup!
Delete the offending calendars:-- Replace <account_id> with the id you got from the previous step, in my case 16 sqlite> DELETE FROM Calendars WHERE account = <account_id>; sqlite> DELETE FROM Calendarproperties WHERE CalendarId NOT IN (SELECT CalendarId FROM Calendars);
-
Show events without calendars and make sure they can be deleted:
sqlite> SELECT Summary, datetime(DateStart, 'unixepoch') as DateStart FROM Components WHERE Notebook NOT IN (SELECT CalendarId FROM Calendars) ORDER BY DateStart; -- Output redacted due to privacy reasons :)
If all is okay, actually delete them and remaining records related to these events:
sqlite> DELETE FROM Components WHERE Notebook NOT IN (SELECT CalendarId FROM Calendars); sqlite> DELETE FROM Attachments WHERE ComponentId NOT IN (SELECT ComponentID FROM Components); sqlite> DELETE FROM Attendee WHERE ComponentId NOT IN (SELECT ComponentID FROM Components); sqlite> DELETE FROM Alarm WHERE ComponentId NOT IN (SELECT ComponentID FROM Components); sqlite> DELETE FROM Customproperties WHERE ComponentId NOT IN (SELECT ComponentID FROM Components); sqlite> DELETE FROM Rdates WHERE ComponentId NOT IN (SELECT ComponentID FROM Components); sqlite> DELETE FROM Recursive WHERE ComponentId NOT IN (SELECT ComponentID FROM Components);
This worked for me for now.
If at any point you messed up, you can run the following command in the sqlite3 shell with the calendar db open (see step 2):
sqlite> .restore calendar.db.bak