Add sync_changes to CalendarStore

This commit is contained in:
Lennart
2024-08-02 20:36:37 +02:00
parent 2bc9635501
commit c50485f13d
3 changed files with 69 additions and 1 deletions

View File

@@ -13,3 +13,23 @@ pub struct Calendar {
pub deleted_at: Option<NaiveDateTime>, pub deleted_at: Option<NaiveDateTime>,
pub synctoken: i64, pub synctoken: i64,
} }
impl Calendar {
pub fn format_synctoken(&self) -> String {
format_synctoken(self.synctoken)
}
}
const SYNC_NAMESPACE: &str = "github.com/lennart-k/rustical/ns/";
pub fn format_synctoken(synctoken: i64) -> String {
format!("{}{}", SYNC_NAMESPACE, synctoken)
}
pub fn parse_synctoken(synctoken: &str) -> Option<i64> {
if !synctoken.starts_with(SYNC_NAMESPACE) {
return None;
}
let (_, synctoken) = synctoken.split_at(SYNC_NAMESPACE.len());
synctoken.parse::<i64>().ok()
}

View File

@@ -32,7 +32,7 @@ impl TryFrom<EventRow> for Event {
} }
} }
#[derive(Serialize, sqlx::Type)] #[derive(Debug, Clone, Serialize, sqlx::Type)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
enum CalendarChangeOperation { enum CalendarChangeOperation {
// There's no distinction between Add and Modify // There's no distinction between Add and Modify
@@ -308,6 +308,47 @@ impl CalendarStore for SqliteCalendarStore {
tx.commit().await?; tx.commit().await?;
Ok(()) Ok(())
} }
async fn sync_changes(
&self,
principal: &str,
cid: &str,
synctoken: i64,
) -> Result<(Vec<Event>, Vec<String>, i64), Error> {
struct Row {
uid: String,
synctoken: i64,
}
let changes = sqlx::query_as!(
Row,
r#"
SELECT DISTINCT uid, max(0, synctoken) as "synctoken!: i64" from eventchangelog
WHERE synctoken > ?
ORDER BY synctoken ASC
"#,
synctoken
)
.fetch_all(&self.db)
.await?;
let mut events = vec![];
let mut deleted_events = vec![];
let new_synctoken = changes
.last()
.map(|&Row { synctoken, .. }| synctoken)
.unwrap_or(0);
for Row { uid, .. } in changes {
match self.get_event(principal, cid, &uid).await {
Ok(event) => events.push(event),
Err(Error::NotFound) => deleted_events.push(uid),
Err(err) => return Err(err),
}
}
Ok((events, deleted_events, new_synctoken))
}
} }
pub async fn create_db_pool(db_url: &str, migrate: bool) -> anyhow::Result<Pool<Sqlite>> { pub async fn create_db_pool(db_url: &str, migrate: bool) -> anyhow::Result<Pool<Sqlite>> {

View File

@@ -24,6 +24,13 @@ pub trait CalendarStore: Send + Sync + 'static {
) -> Result<(), Error>; ) -> Result<(), Error>;
async fn restore_calendar(&mut self, principal: &str, name: &str) -> Result<(), Error>; async fn restore_calendar(&mut self, principal: &str, name: &str) -> Result<(), Error>;
async fn sync_changes(
&self,
principal: &str,
cid: &str,
synctoken: i64,
) -> Result<(Vec<Event>, Vec<String>, i64), Error>;
async fn get_events(&self, principal: &str, cid: &str) -> Result<Vec<Event>, Error>; async fn get_events(&self, principal: &str, cid: &str) -> Result<Vec<Event>, Error>;
async fn get_event(&self, principal: &str, cid: &str, uid: &str) -> Result<Event, Error>; async fn get_event(&self, principal: &str, cid: &str, uid: &str) -> Result<Event, Error>;
async fn put_event( async fn put_event(