mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-14 14:02:29 +00:00
Add sync_changes to CalendarStore
This commit is contained in:
@@ -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()
|
||||||
|
}
|
||||||
|
|||||||
@@ -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>> {
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user