diff --git a/.sqlx/query-11d6a5b6c273bb60434061846f1fa292d8e9b7d898bbdd1169fe6d4edf1c5758.json b/.sqlx/query-11d6a5b6c273bb60434061846f1fa292d8e9b7d898bbdd1169fe6d4edf1c5758.json deleted file mode 100644 index c714b37..0000000 --- a/.sqlx/query-11d6a5b6c273bb60434061846f1fa292d8e9b7d898bbdd1169fe6d4edf1c5758.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "DELETE FROM calendarobjects WHERE cid = ? AND uid = ?", - "describe": { - "columns": [], - "parameters": { - "Right": 2 - }, - "nullable": [] - }, - "hash": "11d6a5b6c273bb60434061846f1fa292d8e9b7d898bbdd1169fe6d4edf1c5758" -} diff --git a/.sqlx/query-2834e16e6a7acb58141a2433f7735d5e2bf913c30f9f3e7bd9fecc7d4376be0f.json b/.sqlx/query-2834e16e6a7acb58141a2433f7735d5e2bf913c30f9f3e7bd9fecc7d4376be0f.json deleted file mode 100644 index 54384e5..0000000 --- a/.sqlx/query-2834e16e6a7acb58141a2433f7735d5e2bf913c30f9f3e7bd9fecc7d4376be0f.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "DELETE FROM calendars WHERE (principal, id) = (?, ?)", - "describe": { - "columns": [], - "parameters": { - "Right": 2 - }, - "nullable": [] - }, - "hash": "2834e16e6a7acb58141a2433f7735d5e2bf913c30f9f3e7bd9fecc7d4376be0f" -} diff --git a/.sqlx/query-3f600740417b6fd02eb347c24302d3fe2f87dbb09c035f9ad665a5b0f6234701.json b/.sqlx/query-3f600740417b6fd02eb347c24302d3fe2f87dbb09c035f9ad665a5b0f6234701.json deleted file mode 100644 index 0c8bc94..0000000 --- a/.sqlx/query-3f600740417b6fd02eb347c24302d3fe2f87dbb09c035f9ad665a5b0f6234701.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "REPLACE INTO calendarobjects (principal, cid, uid, ics) VALUES (?, ?, ?, ?)", - "describe": { - "columns": [], - "parameters": { - "Right": 4 - }, - "nullable": [] - }, - "hash": "3f600740417b6fd02eb347c24302d3fe2f87dbb09c035f9ad665a5b0f6234701" -} diff --git a/.sqlx/query-3fb50028a203f9865d9440bfd5ef2bbcac61cee89d366aa8b0a9d535b49a3669.json b/.sqlx/query-3fb50028a203f9865d9440bfd5ef2bbcac61cee89d366aa8b0a9d535b49a3669.json deleted file mode 100644 index a63c3e8..0000000 --- a/.sqlx/query-3fb50028a203f9865d9440bfd5ef2bbcac61cee89d366aa8b0a9d535b49a3669.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT uid, ics FROM calendarobjects WHERE (principal, cid, uid) = (?, ?, ?)", - "describe": { - "columns": [ - { - "name": "uid", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "ics", - "ordinal": 1, - "type_info": "Text" - } - ], - "parameters": { - "Right": 3 - }, - "nullable": [ - false, - false - ] - }, - "hash": "3fb50028a203f9865d9440bfd5ef2bbcac61cee89d366aa8b0a9d535b49a3669" -} diff --git a/.sqlx/query-c7a56d737fc8627427d0be202c3c77bb95c1a25b6a3c0c389ef0ad4f468320ee.json b/.sqlx/query-c7a56d737fc8627427d0be202c3c77bb95c1a25b6a3c0c389ef0ad4f468320ee.json deleted file mode 100644 index 79cd4da..0000000 --- a/.sqlx/query-c7a56d737fc8627427d0be202c3c77bb95c1a25b6a3c0c389ef0ad4f468320ee.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "UPDATE calendars SET principal = ?, id = ?, displayname = ?, description = ?, \"order\" = ?, color = ?, timezone = ?\n WHERE (principal, id) = (?, ?)", - "describe": { - "columns": [], - "parameters": { - "Right": 9 - }, - "nullable": [] - }, - "hash": "c7a56d737fc8627427d0be202c3c77bb95c1a25b6a3c0c389ef0ad4f468320ee" -} diff --git a/.sqlx/query-cbfcbe0e211d6104bd0120fb0eb28e6b8420f749a4071919bf2a83e26454a694.json b/.sqlx/query-cbfcbe0e211d6104bd0120fb0eb28e6b8420f749a4071919bf2a83e26454a694.json deleted file mode 100644 index b36b718..0000000 --- a/.sqlx/query-cbfcbe0e211d6104bd0120fb0eb28e6b8420f749a4071919bf2a83e26454a694.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT uid, ics FROM calendarobjects WHERE principal = ? AND cid = ? AND deleted_at IS NULL", - "describe": { - "columns": [ - { - "name": "uid", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "ics", - "ordinal": 1, - "type_info": "Text" - } - ], - "parameters": { - "Right": 2 - }, - "nullable": [ - false, - false - ] - }, - "hash": "cbfcbe0e211d6104bd0120fb0eb28e6b8420f749a4071919bf2a83e26454a694" -} diff --git a/.sqlx/query-d162556505138438dd2b8ae14fffc9279d3a5c5386922fa63361d345bd4f93cb.json b/.sqlx/query-d162556505138438dd2b8ae14fffc9279d3a5c5386922fa63361d345bd4f93cb.json deleted file mode 100644 index 4a520f4..0000000 --- a/.sqlx/query-d162556505138438dd2b8ae14fffc9279d3a5c5386922fa63361d345bd4f93cb.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "UPDATE calendarobjects SET deleted_at = datetime(), updated_at = datetime() WHERE (principal, cid, uid) = (?, ?, ?)", - "describe": { - "columns": [], - "parameters": { - "Right": 3 - }, - "nullable": [] - }, - "hash": "d162556505138438dd2b8ae14fffc9279d3a5c5386922fa63361d345bd4f93cb" -} diff --git a/.sqlx/query-deeee7413b3d03d3a68709ae10bf1d596f54d50f5421142dc02d2d7798be47e1.json b/.sqlx/query-deeee7413b3d03d3a68709ae10bf1d596f54d50f5421142dc02d2d7798be47e1.json deleted file mode 100644 index 49de9ab..0000000 --- a/.sqlx/query-deeee7413b3d03d3a68709ae10bf1d596f54d50f5421142dc02d2d7798be47e1.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "UPDATE calendarobjects SET deleted_at = NULL, updated_at = datetime() WHERE (principal, cid, uid) = (?, ?, ?)", - "describe": { - "columns": [], - "parameters": { - "Right": 3 - }, - "nullable": [] - }, - "hash": "deeee7413b3d03d3a68709ae10bf1d596f54d50f5421142dc02d2d7798be47e1" -} diff --git a/.sqlx/query-ec583c44374b71591c2a76881f5d42826c8b31f06d16a09687de70a881bec57f.json b/.sqlx/query-ec583c44374b71591c2a76881f5d42826c8b31f06d16a09687de70a881bec57f.json deleted file mode 100644 index 9675c5f..0000000 --- a/.sqlx/query-ec583c44374b71591c2a76881f5d42826c8b31f06d16a09687de70a881bec57f.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT DISTINCT uid, max(0, synctoken) as \"synctoken!: i64\" from calendarobjectchangelog\n WHERE synctoken > ?\n ORDER BY synctoken ASC\n ", - "describe": { - "columns": [ - { - "name": "uid", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "synctoken!: i64", - "ordinal": 1, - "type_info": "Null" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false, - null - ] - }, - "hash": "ec583c44374b71591c2a76881f5d42826c8b31f06d16a09687de70a881bec57f" -} diff --git a/.sqlx/query-f13006549869125c63731055d242bc29f66761eb52adcb16cde56d56ab5c1ecf.json b/.sqlx/query-f13006549869125c63731055d242bc29f66761eb52adcb16cde56d56ab5c1ecf.json deleted file mode 100644 index f75d93b..0000000 --- a/.sqlx/query-f13006549869125c63731055d242bc29f66761eb52adcb16cde56d56ab5c1ecf.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO calendarobjectchangelog (principal, cid, uid, operation, synctoken)\n VALUES (?1, ?2, ?3, ?4, (\n SELECT synctoken FROM calendars WHERE (principal, id) = (?1, ?2)\n ))", - "describe": { - "columns": [], - "parameters": { - "Right": 4 - }, - "nullable": [] - }, - "hash": "f13006549869125c63731055d242bc29f66761eb52adcb16cde56d56ab5c1ecf" -} diff --git a/crates/caldav/src/calendar/methods/mkcalendar.rs b/crates/caldav/src/calendar/methods/mkcalendar.rs index b8824de..b4e7de0 100644 --- a/crates/caldav/src/calendar/methods/mkcalendar.rs +++ b/crates/caldav/src/calendar/methods/mkcalendar.rs @@ -59,7 +59,7 @@ pub async fn route_mkcalendar( user: User, context: Data>, ) -> Result { - let (principal, cid) = path.into_inner(); + let (principal, cal_id) = path.into_inner(); if principal != user.id { return Err(Error::Unauthorized); } @@ -68,7 +68,7 @@ pub async fn route_mkcalendar( let request = request.set.prop; let calendar = Calendar { - id: cid.to_owned(), + id: cal_id.to_owned(), principal: principal.to_owned(), order: request.order.unwrap_or(0), displayname: request.displayname, @@ -83,7 +83,7 @@ pub async fn route_mkcalendar( .store .read() .await - .get_calendar(&principal, &cid) + .get_calendar(&principal, &cal_id) .await { Err(rustical_store::Error::NotFound) => { diff --git a/crates/caldav/src/calendar/methods/report/calendar_multiget.rs b/crates/caldav/src/calendar/methods/report/calendar_multiget.rs index c26b929..df8ff75 100644 --- a/crates/caldav/src/calendar/methods/report/calendar_multiget.rs +++ b/crates/caldav/src/calendar/methods/report/calendar_multiget.rs @@ -34,10 +34,11 @@ pub async fn get_objects_calendar_multiget( cal_query: &CalendarMultigetRequest, principal_url: &str, principal: &str, - cid: &str, + cal_id: &str, store: &RwLock, ) -> Result<(Vec, Vec), Error> { - let resource_def = ResourceDef::prefix(principal_url).join(&ResourceDef::new("/{cid}/{uid}")); + let resource_def = + ResourceDef::prefix(principal_url).join(&ResourceDef::new("/{cal_id}/{object_id}")); let mut result = vec![]; let mut not_found = vec![]; @@ -48,11 +49,11 @@ pub async fn get_objects_calendar_multiget( if !resource_def.capture_match_info(&mut path) { not_found.push(href.to_owned()); }; - if path.get("cid").unwrap() != cid { + if path.get("cal_id").unwrap() != cal_id { not_found.push(href.to_owned()); } - let uid = path.get("uid").unwrap(); - match store.get_object(principal, cid, uid).await { + let object_id = path.get("object_id").unwrap(); + match store.get_object(principal, cal_id, object_id).await { Ok(object) => result.push(object), Err(rustical_store::Error::NotFound) => not_found.push(href.to_owned()), // TODO: Maybe add error handling on a per-object basis @@ -67,12 +68,12 @@ pub async fn handle_calendar_multiget( cal_multiget: CalendarMultigetRequest, req: HttpRequest, principal: &str, - cid: &str, + cal_id: &str, cal_store: &RwLock, ) -> Result, String>, Error> { let principal_url = PrincipalResource::get_url(req.resource_map(), vec![principal]).unwrap(); let (objects, not_found) = - get_objects_calendar_multiget(&cal_multiget, &principal_url, principal, cid, cal_store) + get_objects_calendar_multiget(&cal_multiget, &principal_url, principal, cal_id, cal_store) .await?; let props = match cal_multiget.prop { @@ -88,7 +89,7 @@ pub async fn handle_calendar_multiget( let mut responses = Vec::new(); for object in objects { - let path = format!("{}/{}", req.path(), object.get_uid()); + let path = format!("{}/{}", req.path(), object.get_id()); responses.push(CalendarObjectResource::from(object).propfind( &path, props.clone(), diff --git a/crates/caldav/src/calendar/methods/report/calendar_query.rs b/crates/caldav/src/calendar/methods/report/calendar_query.rs index 4ba0df5..2ed5e84 100644 --- a/crates/caldav/src/calendar/methods/report/calendar_query.rs +++ b/crates/caldav/src/calendar/methods/report/calendar_query.rs @@ -194,10 +194,10 @@ pub struct CalendarQueryRequest { pub async fn get_objects_calendar_query( cal_query: &CalendarQueryRequest, principal: &str, - cid: &str, + cal_id: &str, store: &RwLock, ) -> Result, Error> { - let mut objects = store.read().await.get_objects(principal, cid).await?; + let mut objects = store.read().await.get_objects(principal, cal_id).await?; if let Some(filter) = &cal_query.filter { objects.retain(|object| filter.matches(object)); } @@ -208,10 +208,10 @@ pub async fn handle_calendar_query( cal_query: CalendarQueryRequest, req: HttpRequest, principal: &str, - cid: &str, + cal_id: &str, cal_store: &RwLock, ) -> Result, String>, Error> { - let objects = get_objects_calendar_query(&cal_query, principal, cid, cal_store).await?; + let objects = get_objects_calendar_query(&cal_query, principal, cal_id, cal_store).await?; let props = match cal_query.prop { PropfindType::Allprop => { @@ -228,7 +228,7 @@ pub async fn handle_calendar_query( for object in objects { let path = CalendarObjectResource::get_url( req.resource_map(), - vec![principal, cid, object.get_uid()], + vec![principal, cal_id, object.get_id()], ) .unwrap(); responses.push(CalendarObjectResource::from(object).propfind( diff --git a/crates/caldav/src/calendar/methods/report/mod.rs b/crates/caldav/src/calendar/methods/report/mod.rs index 6070307..b652d51 100644 --- a/crates/caldav/src/calendar/methods/report/mod.rs +++ b/crates/caldav/src/calendar/methods/report/mod.rs @@ -39,7 +39,7 @@ pub async fn route_report_calendar( req: HttpRequest, cal_store: Data>, ) -> Result { - let (principal, cid) = path.into_inner(); + let (principal, cal_id) = path.into_inner(); if principal != user.id { return Err(Error::Unauthorized); } @@ -48,13 +48,13 @@ pub async fn route_report_calendar( Ok(match request.clone() { ReportRequest::CalendarQuery(cal_query) => { - handle_calendar_query(cal_query, req, &principal, &cid, &cal_store).await? + handle_calendar_query(cal_query, req, &principal, &cal_id, &cal_store).await? } ReportRequest::CalendarMultiget(cal_multiget) => { - handle_calendar_multiget(cal_multiget, req, &principal, &cid, &cal_store).await? + handle_calendar_multiget(cal_multiget, req, &principal, &cal_id, &cal_store).await? } ReportRequest::SyncCollection(sync_collection) => { - handle_sync_collection(sync_collection, req, &principal, &cid, &cal_store).await? + handle_sync_collection(sync_collection, req, &principal, &cal_id, &cal_store).await? } }) } diff --git a/crates/caldav/src/calendar/methods/report/sync_collection.rs b/crates/caldav/src/calendar/methods/report/sync_collection.rs index 3b101ae..201c8e7 100644 --- a/crates/caldav/src/calendar/methods/report/sync_collection.rs +++ b/crates/caldav/src/calendar/methods/report/sync_collection.rs @@ -46,7 +46,7 @@ pub async fn handle_sync_collection( sync_collection: SyncCollectionRequest, req: HttpRequest, principal: &str, - cid: &str, + cal_id: &str, cal_store: &RwLock, ) -> Result, String>, Error> { let props = match sync_collection.prop { @@ -64,14 +64,14 @@ pub async fn handle_sync_collection( let (new_objects, deleted_objects, new_synctoken) = cal_store .read() .await - .sync_changes(principal, cid, old_synctoken) + .sync_changes(principal, cal_id, old_synctoken) .await?; let mut responses = Vec::new(); for object in new_objects { let path = CalendarObjectResource::get_url( req.resource_map(), - vec![principal, cid, &object.get_uid()], + vec![principal, cal_id, &object.get_id()], ) .unwrap(); responses.push(CalendarObjectResource::from(object).propfind( @@ -81,10 +81,12 @@ pub async fn handle_sync_collection( )?); } - for object_uid in deleted_objects { - let path = - CalendarObjectResource::get_url(req.resource_map(), vec![principal, cid, &object_uid]) - .unwrap(); + for object_id in deleted_objects { + let path = CalendarObjectResource::get_url( + req.resource_map(), + vec![principal, cal_id, &object_id], + ) + .unwrap(); responses.push(ResponseElement { href: path, status: Some(format!("HTTP/1.1 {}", StatusCode::NOT_FOUND)), diff --git a/crates/caldav/src/calendar/resource.rs b/crates/caldav/src/calendar/resource.rs index 5b86f5c..124c328 100644 --- a/crates/caldav/src/calendar/resource.rs +++ b/crates/caldav/src/calendar/resource.rs @@ -273,7 +273,7 @@ impl ResourceService for CalendarResourceService { ( CalendarObjectResource::get_url( rmap, - vec![&self.principal, &self.calendar_id, object.get_uid()], + vec![&self.principal, &self.calendar_id, object.get_id()], ) .unwrap(), object.into(), diff --git a/crates/caldav/src/calendar_object/methods.rs b/crates/caldav/src/calendar_object/methods.rs index 5001ce5..df3be2b 100644 --- a/crates/caldav/src/calendar_object/methods.rs +++ b/crates/caldav/src/calendar_object/methods.rs @@ -22,8 +22,8 @@ pub async fn get_event( ) -> Result { let CalendarObjectPathComponents { principal, - cid, - uid, + cal_id, + object_id, } = path.into_inner(); if user.id != principal { @@ -34,7 +34,7 @@ pub async fn get_event( .store .read() .await - .get_calendar(&principal, &cid) + .get_calendar(&principal, &cal_id) .await?; if user.id != calendar.principal { return Ok(HttpResponse::Unauthorized().body("")); @@ -44,7 +44,7 @@ pub async fn get_event( .store .read() .await - .get_object(&principal, &cid, &uid) + .get_object(&principal, &cal_id, &object_id) .await?; Ok(HttpResponse::Ok() @@ -64,8 +64,8 @@ pub async fn put_event( ) -> Result { let CalendarObjectPathComponents { principal, - cid, - uid, + cal_id, + object_id, } = path.into_inner(); if user.id != principal { @@ -76,7 +76,7 @@ pub async fn put_event( .store .read() .await - .get_calendar(&principal, &cid) + .get_calendar(&principal, &cal_id) .await?; if user.id != calendar.principal { return Ok(HttpResponse::Unauthorized().body("")); @@ -89,7 +89,7 @@ pub async fn put_event( if Some(&HeaderValue::from_static("*")) == req.headers().get(header::IF_NONE_MATCH) { // Only write if not existing - match store.get_object(&principal, &cid, &uid).await { + match store.get_object(&principal, &cal_id, &object_id).await { Ok(_) => { // Conflict return Ok(HttpResponse::Conflict().body("Resource with this URI already exists")); @@ -104,8 +104,8 @@ pub async fn put_event( } } - let object = CalendarObject::from_ics(uid, body)?; - store.put_object(principal, cid, object).await?; + let object = CalendarObject::from_ics(object_id, body)?; + store.put_object(principal, cal_id, object).await?; Ok(HttpResponse::Created().body("")) } diff --git a/crates/caldav/src/calendar_object/resource.rs b/crates/caldav/src/calendar_object/resource.rs index 18bf803..da1fade 100644 --- a/crates/caldav/src/calendar_object/resource.rs +++ b/crates/caldav/src/calendar_object/resource.rs @@ -16,8 +16,8 @@ pub struct CalendarObjectResourceService { pub cal_store: Arc>, pub path: String, pub principal: String, - pub cid: String, - pub uid: String, + pub cal_id: String, + pub object_id: String, } #[derive(EnumString, Debug, VariantNames, Clone)] @@ -78,8 +78,8 @@ impl Resource for CalendarObjectResource { #[derive(Debug, Clone)] pub struct CalendarObjectPathComponents { pub principal: String, - pub cid: String, - pub uid: String, + pub cal_id: String, + pub object_id: String, } impl<'de> Deserialize<'de> for CalendarObjectPathComponents { @@ -94,8 +94,8 @@ impl<'de> Deserialize<'de> for CalendarObjectPathComponents { } Ok(Self { principal, - cid: calendar, - uid: object, + cal_id: calendar, + object_id: object, }) } } @@ -113,8 +113,8 @@ impl ResourceService for CalendarObjectResourceServic ) -> Result { let CalendarObjectPathComponents { principal, - cid, - uid, + cal_id, + object_id, } = path_components; let cal_store = req @@ -126,8 +126,8 @@ impl ResourceService for CalendarObjectResourceServic Ok(Self { cal_store, principal, - cid, - uid, + cal_id, + object_id, path: req.path().to_string(), }) } @@ -140,7 +140,7 @@ impl ResourceService for CalendarObjectResourceServic .cal_store .read() .await - .get_object(&self.principal, &self.cid, &self.uid) + .get_object(&self.principal, &self.cal_id, &self.object_id) .await?; Ok(event.into()) } @@ -153,7 +153,7 @@ impl ResourceService for CalendarObjectResourceServic self.cal_store .write() .await - .delete_object(&self.principal, &self.cid, &self.uid, use_trashbin) + .delete_object(&self.principal, &self.cal_id, &self.object_id, use_trashbin) .await?; Ok(()) } diff --git a/crates/frontend/src/lib.rs b/crates/frontend/src/lib.rs index efd9e41..1cba4ed 100644 --- a/crates/frontend/src/lib.rs +++ b/crates/frontend/src/lib.rs @@ -52,10 +52,10 @@ async fn route_calendar( store: Data>, ) -> impl Responder { let store = store.read().await; - let (owner, cid) = path.into_inner(); + let (owner, cal_id) = path.into_inner(); CalendarPage { owner: owner.to_owned(), - calendar: store.get_calendar(&owner, &cid).await.unwrap(), + calendar: store.get_calendar(&owner, &cal_id).await.unwrap(), } } diff --git a/crates/store/migrations/1_init.sql b/crates/store/migrations/1_init.sql index fefdfb1..44ef346 100644 --- a/crates/store/migrations/1_init.sql +++ b/crates/store/migrations/1_init.sql @@ -13,25 +13,25 @@ CREATE TABLE calendars ( CREATE TABLE calendarobjects ( principal TEXT NOT NULL, - cid TEXT NOT NULL, - uid TEXT NOT NULL, + cal_id TEXT NOT NULL, + id TEXT NOT NULL, ics TEXT NOT NULL, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, deleted_at DATETIME, - PRIMARY KEY (principal, cid, uid), - FOREIGN KEY (principal, cid) + PRIMARY KEY (principal, cal_id, id), + FOREIGN KEY (principal, cal_id) REFERENCES calendars (principal, id) ON DELETE CASCADE ); CREATE TABLE calendarobjectchangelog ( -- The actual sync token is the SQLite field 'ROWID' principal TEXT NOT NULL, - cid TEXT NOT NULL, - uid TEXT NOT NULL, + cal_id TEXT NOT NULL, + object_id TEXT NOT NULL, operation INTEGER NOT NULL, synctoken INTEGER DEFAULT 0 NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (principal, cid, created_at), - FOREIGN KEY (principal, cid) + PRIMARY KEY (principal, cal_id, created_at), + FOREIGN KEY (principal, cal_id) REFERENCES calendars (principal, id) ON DELETE CASCADE ); diff --git a/crates/store/src/calendar_store.rs b/crates/store/src/calendar_store.rs index a39b253..ab67477 100644 --- a/crates/store/src/calendar_store.rs +++ b/crates/store/src/calendar_store.rs @@ -28,29 +28,38 @@ pub trait CalendarStore: Send + Sync + 'static { async fn sync_changes( &self, principal: &str, - cid: &str, + cal_id: &str, synctoken: i64, ) -> Result<(Vec, Vec, i64), Error>; - async fn get_objects(&self, principal: &str, cid: &str) -> Result, Error>; + async fn get_objects( + &self, + principal: &str, + cal_id: &str, + ) -> Result, Error>; async fn get_object( &self, principal: &str, - cid: &str, - uid: &str, + cal_id: &str, + object_id: &str, ) -> Result; async fn put_object( &mut self, principal: String, - cid: String, + cal_id: String, object: CalendarObject, ) -> Result<(), Error>; async fn delete_object( &mut self, principal: &str, - cid: &str, - uid: &str, + cal_id: &str, + object_id: &str, use_trashbin: bool, ) -> Result<(), Error>; - async fn restore_object(&mut self, principal: &str, cid: &str, uid: &str) -> Result<(), Error>; + async fn restore_object( + &mut self, + principal: &str, + cal_id: &str, + object_id: &str, + ) -> Result<(), Error>; } diff --git a/crates/store/src/model/object.rs b/crates/store/src/model/object.rs index 3bce639..ece295a 100644 --- a/crates/store/src/model/object.rs +++ b/crates/store/src/model/object.rs @@ -22,7 +22,7 @@ pub enum CalendarObjectComponent { #[derive(Debug, Clone)] pub struct CalendarObject { - uid: String, + id: String, ics: String, data: CalendarObjectComponent, } @@ -35,11 +35,11 @@ impl<'de> Deserialize<'de> for CalendarObject { { #[derive(Deserialize)] struct Inner { - uid: String, + id: String, ics: String, } - let Inner { uid, ics } = Inner::deserialize(deserializer)?; - Self::from_ics(uid, ics).map_err(serde::de::Error::custom) + let Inner { id, ics } = Inner::deserialize(deserializer)?; + Self::from_ics(id, ics).map_err(serde::de::Error::custom) } } @@ -50,12 +50,12 @@ impl Serialize for CalendarObject { { #[derive(Serialize)] struct Inner { - uid: String, + id: String, ics: String, } Inner::serialize( &Inner { - uid: self.get_uid().to_string(), + id: self.get_id().to_string(), ics: self.get_ics().to_string(), }, serializer, @@ -64,7 +64,7 @@ impl Serialize for CalendarObject { } impl CalendarObject { - pub fn from_ics(uid: String, ics: String) -> Result { + pub fn from_ics(object_id: String, ics: String) -> Result { let mut parser = ical::IcalParser::new(BufReader::new(ics.as_bytes())); let cal = parser.next().ok_or(Error::NotFound)??; if parser.next().is_some() { @@ -98,7 +98,7 @@ impl CalendarObject { if let Some(event) = cal.events.first() { return Ok(CalendarObject { - uid, + id: object_id, ics, data: CalendarObjectComponent::Event(EventObject { event: event.clone(), @@ -108,7 +108,7 @@ impl CalendarObject { } if let Some(todo) = cal.todos.first() { return Ok(CalendarObject { - uid, + id: object_id, ics, data: CalendarObjectComponent::Todo(TodoObject { todo: todo.clone() }), }); @@ -119,12 +119,12 @@ impl CalendarObject { )) } - pub fn get_uid(&self) -> &str { - &self.uid + pub fn get_id(&self) -> &str { + &self.id } pub fn get_etag(&self) -> String { let mut hasher = Sha256::new(); - hasher.update(&self.uid); + hasher.update(&self.id); hasher.update(self.get_ics()); format!("{:x}", hasher.finalize()) } diff --git a/crates/store/src/sqlite_store.rs b/crates/store/src/sqlite_store.rs index 0d6f9c9..d45eec4 100644 --- a/crates/store/src/sqlite_store.rs +++ b/crates/store/src/sqlite_store.rs @@ -21,7 +21,7 @@ impl SqliteCalendarStore { #[derive(Debug, Clone)] struct CalendarObjectRow { - uid: String, + id: String, ics: String, } @@ -29,7 +29,7 @@ impl TryFrom for CalendarObject { type Error = Error; fn try_from(value: CalendarObjectRow) -> Result { - CalendarObject::from_ics(value.uid, value.ics) + CalendarObject::from_ics(value.id, value.ics) } } @@ -45,8 +45,8 @@ enum CalendarChangeOperation { async fn log_object_operation( tx: &mut Transaction<'_, Sqlite>, principal: &str, - cid: &str, - uid: &str, + cal_id: &str, + object_id: &str, operation: CalendarChangeOperation, ) -> Result<(), Error> { sqlx::query!( @@ -55,20 +55,20 @@ async fn log_object_operation( SET synctoken = synctoken + 1 WHERE (principal, id) = (?1, ?2)"#, principal, - cid + cal_id ) .execute(&mut **tx) .await?; sqlx::query!( r#" - INSERT INTO calendarobjectchangelog (principal, cid, uid, operation, synctoken) + INSERT INTO calendarobjectchangelog (principal, cal_id, object_id, operation, synctoken) VALUES (?1, ?2, ?3, ?4, ( SELECT synctoken FROM calendars WHERE (principal, id) = (?1, ?2) ))"#, principal, - cid, - uid, + cal_id, + object_id, operation ) .execute(&mut **tx) @@ -194,12 +194,16 @@ impl CalendarStore for SqliteCalendarStore { } #[instrument] - async fn get_objects(&self, principal: &str, cid: &str) -> Result, Error> { + async fn get_objects( + &self, + principal: &str, + cal_id: &str, + ) -> Result, Error> { sqlx::query_as!( CalendarObjectRow, - "SELECT uid, ics FROM calendarobjects WHERE principal = ? AND cid = ? AND deleted_at IS NULL", + "SELECT id, ics FROM calendarobjects WHERE principal = ? AND cal_id = ? AND deleted_at IS NULL", principal, - cid + cal_id ) .fetch_all(&self.db) .await? @@ -212,15 +216,15 @@ impl CalendarStore for SqliteCalendarStore { async fn get_object( &self, principal: &str, - cid: &str, - uid: &str, + cal_id: &str, + object_id: &str, ) -> Result { Ok(sqlx::query_as!( CalendarObjectRow, - "SELECT uid, ics FROM calendarobjects WHERE (principal, cid, uid) = (?, ?, ?)", + "SELECT id, ics FROM calendarobjects WHERE (principal, cal_id, id) = (?, ?, ?)", principal, - cid, - uid + cal_id, + object_id ) .fetch_one(&self.db) .await? @@ -231,24 +235,31 @@ impl CalendarStore for SqliteCalendarStore { async fn put_object( &mut self, principal: String, - cid: String, + cal_id: String, object: CalendarObject, ) -> Result<(), Error> { let mut tx = self.db.begin().await?; - let (uid, ics) = (object.get_uid(), object.get_ics()); + let (object_id, ics) = (object.get_id(), object.get_ics()); sqlx::query!( - "REPLACE INTO calendarobjects (principal, cid, uid, ics) VALUES (?, ?, ?, ?)", + "REPLACE INTO calendarobjects (principal, cal_id, id, ics) VALUES (?, ?, ?, ?)", principal, - cid, - uid, + cal_id, + object_id, ics ) .execute(&mut *tx) .await?; - log_object_operation(&mut tx, &principal, &cid, uid, CalendarChangeOperation::Add).await?; + log_object_operation( + &mut tx, + &principal, + &cal_id, + object_id, + CalendarChangeOperation::Add, + ) + .await?; tx.commit().await?; Ok(()) @@ -258,8 +269,8 @@ impl CalendarStore for SqliteCalendarStore { async fn delete_object( &mut self, principal: &str, - cid: &str, - uid: &str, + cal_id: &str, + id: &str, use_trashbin: bool, ) -> Result<(), Error> { let mut tx = self.db.begin().await?; @@ -267,19 +278,19 @@ impl CalendarStore for SqliteCalendarStore { match use_trashbin { true => { sqlx::query!( - "UPDATE calendarobjects SET deleted_at = datetime(), updated_at = datetime() WHERE (principal, cid, uid) = (?, ?, ?)", + "UPDATE calendarobjects SET deleted_at = datetime(), updated_at = datetime() WHERE (principal, cal_id, id) = (?, ?, ?)", principal, - cid, - uid + cal_id, + id ) .execute(&mut *tx) .await?; } false => { sqlx::query!( - "DELETE FROM calendarobjects WHERE cid = ? AND uid = ?", - cid, - uid + "DELETE FROM calendarobjects WHERE cal_id = ? AND id = ?", + cal_id, + id ) .execute(&mut *tx) .await?; @@ -288,8 +299,8 @@ impl CalendarStore for SqliteCalendarStore { log_object_operation( &mut tx, principal, - cid, - uid, + cal_id, + id, CalendarChangeOperation::Delete, ) .await?; @@ -298,14 +309,19 @@ impl CalendarStore for SqliteCalendarStore { } #[instrument] - async fn restore_object(&mut self, principal: &str, cid: &str, uid: &str) -> Result<(), Error> { + async fn restore_object( + &mut self, + principal: &str, + cal_id: &str, + object_id: &str, + ) -> Result<(), Error> { let mut tx = self.db.begin().await?; sqlx::query!( - r#"UPDATE calendarobjects SET deleted_at = NULL, updated_at = datetime() WHERE (principal, cid, uid) = (?, ?, ?)"#, + r#"UPDATE calendarobjects SET deleted_at = NULL, updated_at = datetime() WHERE (principal, cal_id, id) = (?, ?, ?)"#, principal, - cid, - uid + cal_id, + object_id ) .execute(&mut *tx) .await?; @@ -313,8 +329,8 @@ impl CalendarStore for SqliteCalendarStore { log_object_operation( &mut tx, principal, - cid, - uid, + cal_id, + object_id, CalendarChangeOperation::Delete, ) .await?; @@ -326,17 +342,17 @@ impl CalendarStore for SqliteCalendarStore { async fn sync_changes( &self, principal: &str, - cid: &str, + cal_id: &str, synctoken: i64, ) -> Result<(Vec, Vec, i64), Error> { struct Row { - uid: String, + object_id: String, synctoken: i64, } let changes = sqlx::query_as!( Row, r#" - SELECT DISTINCT uid, max(0, synctoken) as "synctoken!: i64" from calendarobjectchangelog + SELECT DISTINCT object_id, max(0, synctoken) as "synctoken!: i64" from calendarobjectchangelog WHERE synctoken > ? ORDER BY synctoken ASC "#, @@ -353,10 +369,10 @@ impl CalendarStore for SqliteCalendarStore { .map(|&Row { synctoken, .. }| synctoken) .unwrap_or(0); - for Row { uid, .. } in changes { - match self.get_object(principal, cid, &uid).await { + for Row { object_id, .. } in changes { + match self.get_object(principal, cal_id, &object_id).await { Ok(object) => objects.push(object), - Err(Error::NotFound) => deleted_objects.push(uid), + Err(Error::NotFound) => deleted_objects.push(object_id), Err(err) => return Err(err), } } diff --git a/crates/store/tests/test_calendar.rs b/crates/store/tests/test_calendar.rs index fd5a53b..eeef6e8 100644 --- a/crates/store/tests/test_calendar.rs +++ b/crates/store/tests/test_calendar.rs @@ -44,5 +44,5 @@ async fn test_create_event(mut store: CS) { let event = store.get_object("testuser", "test", "asd").await.unwrap(); assert_eq!(event.get_ics(), EVENT); - assert_eq!(event.get_uid(), "asd"); + assert_eq!(event.get_id(), "asd"); }