intelli_shell/storage/
version.rs

1use chrono::{DateTime, Utc};
2use semver::Version;
3use tracing::instrument;
4
5use super::SqliteStorage;
6use crate::errors::Result;
7
8impl SqliteStorage {
9    /// Gets the current version info from the database
10    #[instrument(skip_all)]
11    pub async fn get_version_info(&self) -> Result<(Version, DateTime<Utc>)> {
12        self.client
13            .conn(move |conn| {
14                let query = "SELECT latest_version, last_checked_at FROM version_info LIMIT 1";
15                tracing::trace!("Checking version info: {query}");
16                Ok(conn.query_one(query, [], |r| {
17                    Ok((
18                        Version::parse(&r.get::<_, String>(0)?).expect("valid version"),
19                        r.get(1)?,
20                    ))
21                })?)
22            })
23            .await
24    }
25
26    /// Updates the version info in the database
27    #[instrument(skip_all)]
28    pub async fn update_version_info(&self, latest_version: Version, last_checked_at: DateTime<Utc>) -> Result<()> {
29        self.client
30            .conn_mut(move |conn| {
31                let query = "UPDATE version_info SET latest_version = ?1, last_checked_at = ?2";
32                tracing::trace!("Updating version info: {query}");
33                Ok(conn.execute(query, (latest_version.to_string(), last_checked_at))?)
34            })
35            .await?;
36        Ok(())
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use chrono::Utc;
43    use pretty_assertions::assert_eq;
44
45    use super::*;
46
47    #[tokio::test]
48    async fn test_get_and_update_version_info() {
49        let storage = SqliteStorage::new_in_memory().await.unwrap();
50
51        // There should always be a row in version_info after migrations
52        let (version, checked_at) = storage.get_version_info().await.unwrap();
53        assert_eq!(version, Version::parse("0.0.0").unwrap());
54        assert!(checked_at <= Utc::now());
55
56        // Update version info
57        let new_version = Version::parse("1.2.3").unwrap();
58        let new_checked_at = Utc::now();
59        storage
60            .update_version_info(new_version.clone(), new_checked_at)
61            .await
62            .unwrap();
63
64        // Check that the update is reflected
65        let (updated_version, updated_checked_at) = storage.get_version_info().await.unwrap();
66        assert_eq!(updated_version, new_version);
67        assert_eq!(updated_checked_at.timestamp(), new_checked_at.timestamp());
68    }
69}