From 3a88c7ba3df5ebf92f1975863d35116a2678e626 Mon Sep 17 00:00:00 2001 From: Pete Gadomski Date: Wed, 20 Sep 2023 05:11:33 -0600 Subject: [PATCH] feat: get/set context --- src/client.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/lib.rs | 3 +- src/page.rs | 33 +++++++++++++++++-- 3 files changed, 114 insertions(+), 9 deletions(-) diff --git a/src/client.rs b/src/client.rs index a20b839..0b5cbd1 100644 --- a/src/client.rs +++ b/src/client.rs @@ -18,18 +18,89 @@ where impl<'a, C: GenericClient> Client<'a, C> { /// Creates a new client. + /// + /// # Examples + /// + /// ``` + /// use pgstac::Client; + /// use tokio_postgres::NoTls; + /// + /// let config = "postgresql://username:password@localhost:5432/postgis"; + /// # tokio_test::block_on(async { + /// let (mut client, connection) = tokio_postgres::connect(config, NoTls).await.unwrap(); + /// let client = Client::new(&client); + /// # }); + /// ``` pub fn new(client: &C) -> Client { Client(client) } /// Returns the **pgstac** version. + /// + /// # Examples + /// + /// ```no_run + /// use pgstac::Client; + /// use tokio_postgres::NoTls; + /// let config = "postgresql://username:password@localhost:5432/postgis"; + /// # tokio_test::block_on(async { + /// let (mut client, connection) = tokio_postgres::connect(config, NoTls).await.unwrap(); + /// let client = Client::new(&client); + /// let version = client.version().await.unwrap(); + /// # }); + /// ``` pub async fn version(&self) -> Result { self.string("get_version", &[]).await } - /// Returns the value of a **pgstac** setting. - pub async fn setting(&self, setting: &str) -> Result { - self.string("get_setting", &[&setting]).await + /// Returns the value of the `context` **pgstac** setting. + /// + /// This setting defaults to "off". See [the **pgstac** + /// docs](https://github.com/stac-utils/pgstac/blob/main/docs/src/pgstac.md#pgstac-settings) + /// for more information on the settings and their meaning. + /// + /// # Examples + /// + /// ```no_run + /// use pgstac::Client; + /// use tokio_postgres::NoTls; + /// let config = "postgresql://username:password@localhost:5432/postgis"; + /// # tokio_test::block_on(async { + /// let (mut client, connection) = tokio_postgres::connect(config, NoTls).await.unwrap(); + /// let client = Client::new(&client); + /// assert!(!client.context().await.unwrap()); + /// # }); + /// ``` + pub async fn context(&self) -> Result { + self.string("get_setting", &[&"context"]) + .await + .map(|value| value == "on") + } + + /// Sets the value of the `context` **pgstac** setting. + /// + /// This setting defaults to "off". See [the **pgstac** + /// docs](https://github.com/stac-utils/pgstac/blob/main/docs/src/pgstac.md#pgstac-settings) + /// for more information on the settings and their meaning. + /// + /// # Examples + /// + /// ```no_run + /// use pgstac::Client; + /// use tokio_postgres::NoTls; + /// let config = "postgresql://username:password@localhost:5432/postgis"; + /// # tokio_test::block_on(async { + /// let (mut client, connection) = tokio_postgres::connect(config, NoTls).await.unwrap(); + /// let client = Client::new(&client); + /// client.set_context(true).await.unwrap(); + /// # }); + /// ``` + pub async fn set_context(&self, enable: bool) -> Result<()> { + let value = if enable { "on" } else { "off" }; + self.0.execute( + "INSERT INTO pgstac_settings (name, value) VALUES ('context', $1) ON CONFLICT ON CONSTRAINT pgstac_settings_pkey DO UPDATE SET value = excluded.value;", + &[&value], + ).await.map(|_| ()).map_err(Error::from) } /// Fetches all collections. @@ -199,8 +270,14 @@ mod tests { } #[pgstac_test] - async fn setting(client: &Client<'_, Transaction<'_>>) { - assert_eq!(client.setting("context").await.unwrap(), "off"); + async fn context(client: &Client<'_, Transaction<'_>>) { + assert!(!client.context().await.unwrap()); + } + + #[pgstac_test] + async fn set_context(client: &Client<'_, Transaction<'_>>) { + client.set_context(true).await.unwrap(); + assert!(client.context().await.unwrap()); } #[pgstac_test] diff --git a/src/lib.rs b/src/lib.rs index 534b0c9..504e232 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,8 @@ //! //! # Examples //! -//! [Client] provides an interface to query a **pgstac** database. It can be created from anything that implements [tokio_postgres::GenericClient]. +//! [Client] provides an interface to query a **pgstac** database. +//! It can be created from anything that implements [tokio_postgres::GenericClient]. //! //! ``` //! use pgstac::Client; diff --git a/src/page.rs b/src/page.rs index ff6b32e..6787647 100644 --- a/src/page.rs +++ b/src/page.rs @@ -1,13 +1,12 @@ use serde::Deserialize; -use serde_json::{Map, Value}; -use stac_api::Context; +use stac_api::{Context, Item}; /// A page of search results. #[derive(Debug, Deserialize)] pub struct Page { /// These are the out features, usually STAC items, but maybe not legal STAC /// items if fields are excluded. - pub features: Vec>, + pub features: Vec, /// The next id. pub next: Option, @@ -21,11 +20,39 @@ pub struct Page { impl Page { /// Returns this page's next token, if it has one. + /// + /// # Examples + /// + /// ```no_run + /// use pgstac::Client; + /// use tokio_postgres::NoTls; + /// let config = "postgresql://username:password@localhost:5432/postgis"; + /// # tokio_test::block_on(async { + /// let (client, connection) = tokio_postgres::connect(config, NoTls).await.unwrap(); + /// let client = Client::new(&client); + /// let page = client.search(Default::default()).await.unwrap(); + /// let next_token = page.next_token().unwrap(); + /// # }); + /// ``` pub fn next_token(&self) -> Option { self.next.as_ref().map(|next| format!("next:{}", next)) } /// Returns this page's prev token, if it has one. + /// + /// # Examples + /// + /// ```no_run + /// use pgstac::Client; + /// use tokio_postgres::NoTls; + /// let config = "postgresql://username:password@localhost:5432/postgis"; + /// # tokio_test::block_on(async { + /// let (client, connection) = tokio_postgres::connect(config, NoTls).await.unwrap(); + /// let client = Client::new(&client); + /// let page = client.search(Default::default()).await.unwrap(); + /// let prev_token = page.prev_token().unwrap(); + /// # }); + /// ``` pub fn prev_token(&self) -> Option { self.prev.as_ref().map(|prev| format!("prev:{}", prev)) }