cognite/api/data_modeling/
instances.rs

1use serde::de::DeserializeOwned;
2use serde::Serialize;
3
4use crate::dto::data_modeling::instances::SlimNodeOrEdge;
5use crate::models::instances::{
6    AggregateInstancesRequest, AggregateInstancesResponse, FilterInstancesRequest,
7    InstancesFilterResponse, NodeAndEdgeCreateCollection, NodeAndEdgeRetrieveRequest,
8    NodeAndEdgeRetrieveResponse, NodeOrEdge, NodeOrEdgeCreate, NodeOrEdgeSpecification,
9    QueryInstancesRequest, QueryInstancesResponse, SearchInstancesRequest, SourceReferenceInternal,
10};
11use crate::models::instances::{FromReadable, WithView};
12use crate::models::views::ViewReference;
13use crate::Result;
14use crate::{DeleteWithResponse, FilterWithRequest, RetrieveWithRequest, UpsertCollection};
15use crate::{Resource, WithBasePath};
16
17/// Instances are nodes and edges in a data model. These contain the actual data in the data model.
18pub type Instances = Resource<SlimNodeOrEdge>;
19
20impl WithBasePath for Instances {
21    const BASE_PATH: &'static str = "models/instances";
22}
23
24impl<TProperties> FilterWithRequest<FilterInstancesRequest, NodeOrEdge<TProperties>> for Instances where
25    TProperties: Serialize + DeserializeOwned + Send + Sync
26{
27}
28impl<TProperties>
29    RetrieveWithRequest<NodeAndEdgeRetrieveRequest, NodeAndEdgeRetrieveResponse<TProperties>>
30    for Instances
31where
32    TProperties: Serialize + DeserializeOwned + Send + Sync,
33{
34}
35impl<TProperties> UpsertCollection<NodeAndEdgeCreateCollection<TProperties>, SlimNodeOrEdge>
36    for Instances
37{
38}
39impl DeleteWithResponse<NodeOrEdgeSpecification, NodeOrEdgeSpecification> for Instances {}
40
41impl Instances {
42    /// Filter instances optionally returning type information.
43    ///
44    /// # Arguments
45    ///
46    /// * `req` - Request with optional filter.
47    pub async fn filter_with_type_info<TProperties: DeserializeOwned + Send + Sync + 'static>(
48        &self,
49        req: FilterInstancesRequest,
50    ) -> Result<InstancesFilterResponse<TProperties>> {
51        self.api_client
52            .post(&format!("{}/list", Self::BASE_PATH), &req)
53            .await
54    }
55
56    /// Perform a complex query against data models.
57    ///
58    /// # Arguments
59    ///
60    /// * `query` - Query to execute.
61    pub async fn query<TProperties: DeserializeOwned + Send + Sync + 'static>(
62        &self,
63        query: QueryInstancesRequest,
64    ) -> Result<QueryInstancesResponse<TProperties>> {
65        self.api_client
66            .post(&format!("{}/query", Self::BASE_PATH), &query)
67            .await
68    }
69
70    /// Perform a complex query against data models. This always returns cursors,
71    /// so you can keep querying to get any changes since the last query.
72    ///
73    /// # Arguments
74    ///
75    /// * `query` - Query to execute.
76    pub async fn sync<TProperties: DeserializeOwned + Send + Sync + 'static>(
77        &self,
78        query: QueryInstancesRequest,
79    ) -> Result<QueryInstancesResponse<TProperties>> {
80        self.api_client
81            .post(&format!("{}/sync", Self::BASE_PATH), &query)
82            .await
83    }
84
85    /// Aggregate nodes and edges.
86    ///
87    /// # Arguments
88    ///
89    /// * `req` - Aggregates to compute.
90    pub async fn aggregate(
91        &self,
92        req: AggregateInstancesRequest,
93    ) -> Result<AggregateInstancesResponse> {
94        self.api_client
95            .post(&format!("{}/aggregate", Self::BASE_PATH), &req)
96            .await
97    }
98
99    /// Search nodes and edges.
100    ///
101    /// # Arguments
102    ///
103    /// * `req` - Search request.
104    pub async fn search<TProperties: DeserializeOwned + Send + Sync + 'static>(
105        &self,
106        req: SearchInstancesRequest,
107    ) -> Result<NodeAndEdgeRetrieveResponse<TProperties>> {
108        self.api_client
109            .post(&format!("{}/search", Self::BASE_PATH), &req)
110            .await
111    }
112
113    /// Fetch special data models instance collection.
114    ///
115    /// # Arguments
116    ///
117    /// * `items` - A list of specifications of node/edges to retrieve.
118    pub async fn fetch<TEntity, TProperties>(
119        &self,
120        items: &[NodeOrEdgeSpecification],
121        view: Option<&ViewReference>,
122    ) -> Result<Vec<TEntity>>
123    where
124        TProperties: Serialize + DeserializeOwned + Send + Sync,
125        TEntity: FromReadable<TProperties> + WithView + Send,
126    {
127        let response: NodeAndEdgeRetrieveResponse<TProperties> = self
128            .retrieve(&NodeAndEdgeRetrieveRequest {
129                sources: Some(vec![SourceReferenceInternal {
130                    source: view
131                        .unwrap_or(&ViewReference {
132                            space: TEntity::SPACE.to_owned(),
133                            external_id: TEntity::EXTERNAL_ID.to_owned(),
134                            version: TEntity::VERSION.to_owned(),
135                        })
136                        .to_owned()
137                        .into(),
138                }]),
139                items: items.to_vec(),
140                include_typing: None,
141            })
142            .await?;
143        response
144            .items
145            .into_iter()
146            .map(|item| TEntity::try_from(item, view))
147            .collect()
148    }
149
150    /// Upsert data models instances of this type.
151    ///
152    /// # Arguments
153    ///
154    /// * `col` - A list of this type to be created.
155    /// * `auto_create_direct_relation` - Whether to auto create direct relation that do no exist.
156    /// * `auto_create_start_nodes` - Whether to auto create end nodes that do not exist.
157    /// * `auto_create_end_nodes` - Whether to auto create end nodes that do not exist.
158    /// * `skip_on_version_conflict` - Whether to skip when a version conflict is encountered.
159    /// * `replace` - Whether to replace all matching and existing values with the supplied values.
160    pub async fn apply<TEntity, TProperties>(
161        &self,
162        col: &[TEntity],
163        auto_create_direct_relations: Option<bool>,
164        auto_create_start_nodes: Option<bool>,
165        auto_create_end_nodes: Option<bool>,
166        skip_on_version_conflict: Option<bool>,
167        replace: bool,
168    ) -> Result<Vec<SlimNodeOrEdge>>
169    where
170        TProperties: Serialize + DeserializeOwned + Send + Sync,
171        TEntity: Clone + Into<NodeOrEdgeCreate<TProperties>> + Send,
172    {
173        let collection = col
174            .iter()
175            .map(|t| t.to_owned().into())
176            .collect::<Vec<NodeOrEdgeCreate<_>>>();
177
178        let collection = NodeAndEdgeCreateCollection {
179            items: collection,
180            auto_create_direct_relations: auto_create_direct_relations.or(Some(true)),
181            auto_create_start_nodes,
182            auto_create_end_nodes,
183            skip_on_version_conflict,
184            replace: Some(replace),
185        };
186        self.upsert(&collection).await
187    }
188}