kdb-connection 0.1.0

kDB connection.
Documentation
//! Convenient API for creating krQL queries
use serde_with::skip_serializing_none;

use super::KRQLQuery;

#[derive(Clone, KRQLQuery)]
#[krql(tag = "action")]
pub enum Agent
{
    /// Create a new collection of agents
    #[serde(rename = "create collection")]
    CreateCollection
    {
        collection_uri: String
    },
    /// Create a new collection of agents
    #[serde(rename = "delete collection")]
    DeleteCollection
    {
        collection_uri: String
    },
    /// A string to print by the kDB Server
    #[serde(rename = "insert agent")]
    #[allow(clippy::enum_variant_names)]
    InsertAgent
    {
        collection_uri: String,
        type_uri: String,
        name: String,
        frame_name: String,
        agent_uri: Option<String>,
    },
    /// A string to print by the kDB Server
    #[serde(rename = "insert stream")]
    InsertStream
    {
        collection_uri: String,
        agent_uri: String,
        content_type_uri: String,
        identifier: String,
        data_type_uri: String,
        stream_uri: Option<String>,
    },
    /// A string to print by the kDB Server
    #[serde(rename = "get all agents")]
    GetAllAgents
    {
        collection_uri: String
    },
    /// A string to print by the kDB Server
    #[serde(rename = "get streams")]
    GetStreams
    {
        collection_uri: String,
        agent_uri: String,
    },
}

#[cfg(test)]
mod tests
{
    use crate::{Connection as _, Value, ValueHash, value::ValueArray};

    use super::*;

    #[test]
    fn test_add_robot_query()
    {
        let t = Agent::InsertAgent {
            collection_uri: "cu".into(),
            type_uri: "tu".into(),
            name: "na".into(),
            frame_name: "fa".into(),
            agent_uri: None,
        };
        assert_eq!(
            serde_saphyr::to_string(&t).unwrap(),
            r#"agent:
  action: insert agent
  collection_uri: cu
  type_uri: tu
  name: na
  frame_name: fa
"#
        );
    }
    #[tokio::test(flavor = "current_thread")]
    async fn test_http_agent_query()
    {
        let mut store = crate::test::create_store(
            crate::test::create_store_configuration()
                .set_web_port(8888)
                .load_extension("kDBRobotics"),
        );
        store.start().unwrap();
        let c = crate::http::Connection::new("http://localhost:8888");
        crate::test::wait_for_connection(&c).await;

        // Create an agent
        let f = c
            .execute_query(Agent::InsertAgent {
                collection_uri: "http://askco.re/graph#private_agents".into(),
                type_uri: "http://askco.re/agent#uav".into(),
                name: "test agent".into(),
                frame_name: "agent0".into(),
                agent_uri: Some("http://example.org/agent/0".into()),
            })
            .unwrap();

        let r = f.await.unwrap();
        assert_eq!(r.metadata.error, String::new());
        assert!(r.metadata.success);

        // Get all the agents
        let f = c
            .execute_query(Agent::GetAllAgents {
                collection_uri: "http://askco.re/graph#private_agents".into(),
            })
            .unwrap();
        let r = f.await.unwrap();
        assert_eq!(r.metadata.error, String::new());
        assert!(r.metadata.success);
        assert_eq!(r.results.bindings.len(), 1);
        let agents = r.results.bindings[0].get("data").unwrap();
        let agents: ValueArray = agents.to_owned().try_into().unwrap();
        assert_eq!(agents.len(), 1);
        let agent_0 = agents.first().unwrap();
        let agent_0: ValueHash = agent_0.to_owned().try_into().unwrap();
        crate::test::validate_agent_0(agent_0);
    }
    #[tokio::test(flavor = "current_thread")]
    async fn test_http_agent_streams_query()
    {
        let mut store = crate::test::create_store(
            crate::test::create_store_configuration()
                .set_web_port(8888)
                .load_extension("kDBRobotics"),
        );
        store.start().unwrap();
        let c = crate::http::Connection::new("http://localhost:8888");
        crate::test::wait_for_connection(&c).await;

        // Create an agent
        let f = c
            .execute_query(Agent::InsertAgent {
                collection_uri: "http://askco.re/graph#private_agents".into(),
                type_uri: "http://askco.re/agent#uav".into(),
                name: "test agent".into(),
                frame_name: "agent0".into(),
                agent_uri: Some("http://example.org/agent/0".into()),
            })
            .unwrap();

        let r = f.await.unwrap();
        assert_eq!(r.metadata.error, String::new());
        assert!(r.metadata.success);

        // Create a stream
        let f = c
            .execute_query(Agent::InsertStream {
                collection_uri: "http://askco.re/graph#private_agents".into(),
                agent_uri: "http://example.org/agent/0".into(),
                content_type_uri: "http://example.org/some/content".into(),
                identifier: "/some/topic".into(),
                data_type_uri: "http://example.org/some/data/type".into(),
                stream_uri: Some("http://example.org/agent/0/data/stream".into()),
            })
            .unwrap();

        let r = f.await.unwrap();
        assert_eq!(r.metadata.error, String::new());
        assert!(r.metadata.success);

        // Get the stream back
        let f = c
            .execute_query(Agent::GetStreams {
                collection_uri: "http://askco.re/graph#private_agents".into(),
                agent_uri: "http://example.org/agent/0".into(),
            })
            .unwrap();
        let r = f.await.unwrap();
        assert_eq!(r.metadata.error, String::new());
        assert!(r.metadata.success);

        assert_eq!(r.results.bindings.len(), 1);
        let streams = r.results.bindings[0].get("data").unwrap();
        let streams: ValueArray = streams.to_owned().try_into().unwrap();
        assert_eq!(streams.len(), 1);
        let stream_0 = streams.first().unwrap();
        let stream_0: ValueHash = stream_0.to_owned().try_into().unwrap();

        // ---- object_uri ----
        let object_uri = stream_0.get("object_uri").unwrap();
        assert_eq!(
            object_uri,
            &Value::from_uri_value(
                "http://www.w3.org/2001/XMLSchema#anyURI",
                "http://example.org/agent/0/data/stream"
            )
        );

        // ---- type_uri ----
        let type_uri = stream_0.get("type_uri").unwrap();
        assert_eq!(
            type_uri,
            &Value::from_uri_value(
                "http://www.w3.org/2001/XMLSchema#anyURI",
                "http://askco.re/agent/stream#stream"
            )
        );

        // ---- properties ----
        let properties_value = stream_0.get("properties").unwrap();
        assert_eq!(
            properties_value.datatype_ref(),
            "http://askco.re/datatype#valuehash"
        );

        let properties_map: ValueHash = properties_value.clone().try_into().unwrap();

        // ---- individual property checks ----
        assert_eq!(
            properties_map
                .get("http://askco.re/agent/stream#data_type")
                .unwrap(),
            &Value::from_uri_value(
                "http://www.w3.org/2001/XMLSchema#anyURI",
                "http://example.org/some/data/type"
            )
        );

        assert_eq!(
            properties_map
                .get("http://askco.re/agent/stream#content_type")
                .unwrap(),
            &Value::from_uri_value(
                "http://www.w3.org/2001/XMLSchema#anyURI",
                "http://example.org/some/content"
            )
        );

        assert_eq!(
            properties_map
                .get("http://askco.re/agent/stream#identifier")
                .unwrap(),
            &Value::from("/some/topic")
        );
    }
}