axone_cognitarium/
msg.rs

1use cosmwasm_schema::{cw_serde, QueryResponses};
2use cosmwasm_std::{Binary, Uint128};
3use derive_builder::Builder;
4use std::collections::BTreeMap;
5
6/// Instantiate message
7#[cw_serde]
8#[derive(Default)]
9pub struct InstantiateMsg {
10    /// Limitations regarding store usage.
11    #[serde(default)]
12    pub limits: StoreLimitsInput,
13}
14
15/// Execute messages
16#[cw_serde]
17pub enum ExecuteMsg {
18    /// # InsertData
19    /// Insert the data as RDF triples in the store.
20    /// For already existing triples it acts as no-op.
21    ///
22    /// Only the smart contract owner (i.e. the address who instantiated it) is authorized to perform
23    /// this action.
24    InsertData {
25        /// The data format in which the triples are serialized.
26        /// If not provided, the default format is [Turtle](https://www.w3.org/TR/turtle/) format.
27        format: Option<DataFormat>,
28        /// The data to insert.
29        /// The data must be serialized in the format specified by the `format` field. And the data
30        /// are subject to the limitations defined by the `limits` specified at contract instantiation.
31        data: Binary,
32    },
33
34    /// # DeleteData
35    /// Delete the data (RDF triples) from the store matching the patterns defined by the provided
36    /// query. For non-existing triples it acts as no-op.
37    ///
38    /// Example:
39    /// ```json
40    /// {
41    ///   "prefixes": [
42    ///     { "prefix": "foaf", "namespace": "http://xmlns.com/foaf/0.1/" }
43    ///   ],
44    ///   "delete": [
45    ///     {
46    ///         "subject": { "variable": "s" },
47    ///         "predicate": { "variable": "p" },
48    ///         "object": { "variable": "o" }
49    ///     }
50    ///   ],
51    ///   "where": [
52    ///     { "simple": { "triplePattern": {
53    ///         "subject": { "variable": "s" },
54    ///         "predicate": { "namedNode": {"prefixed": "foaf:givenName"} },
55    ///         "object": { "literal": { "simple": "Myrddin" } }
56    ///     } } },
57    ///     { "simple": { "triplePattern": {
58    ///         "subject": { "variable": "s" },
59    ///         "predicate": { "variable": "p" },
60    ///         "object": { "variable": "o" }
61    ///     } } }
62    ///  ]
63    /// ```
64    ///
65    /// Only the smart contract owner (i.e. the address who instantiated it) is authorized to perform
66    /// this action.
67    DeleteData {
68        /// The prefixes used in the operation.
69        prefixes: Vec<Prefix>,
70        /// Specifies the specific triple templates to delete.
71        /// If nothing is provided and the `where` clause is a single Bgp, the patterns are used for
72        /// deletion.
73        delete: Vec<TripleDeleteTemplate>,
74        /// Defines the patterns that data (RDF triples) should match in order for it to be
75        /// considered for deletion, if any.
76        r#where: Option<WhereClause>,
77    },
78}
79
80/// # SelectQuery
81/// Query messages
82#[cw_serde]
83#[derive(QueryResponses)]
84pub enum QueryMsg {
85    /// # Store
86    ///
87    /// Returns information about the triple store.
88    #[returns(StoreResponse)]
89    Store {},
90
91    /// # Select
92    ///
93    /// Returns the resources matching the criteria defined by the provided query.
94    ///
95    #[returns(SelectResponse)]
96    Select {
97        /// The query to execute.
98        query: SelectQuery,
99    },
100
101    /// # Describe
102    ///
103    /// Returns a description of the resource identified by the provided IRI as a set of RDF triples
104    /// serialized in the provided format.
105    #[returns(DescribeResponse)]
106    Describe {
107        /// The query to execute.
108        query: DescribeQuery,
109        /// The format in which the triples are serialized.
110        /// If not provided, the default format is [Turtle](https://www.w3.org/TR/turtle/) format.
111        format: Option<DataFormat>,
112    },
113
114    /// # Construct
115    ///
116    /// Returns the resources matching the criteria defined by the provided query as a set of RDF
117    /// triples serialized in the provided format.
118    #[returns(ConstructResponse)]
119    Construct {
120        /// The query to execute.
121        query: ConstructQuery,
122        /// The format in which the triples are serialized.
123        /// If not provided, the default format is [Turtle](https://www.w3.org/TR/turtle/) format.
124        format: Option<DataFormat>,
125    },
126}
127
128/// # DataFormat
129/// Represents the format in which the data are serialized, for example when returned by a query or
130/// when inserted in the store.
131#[cw_serde]
132#[derive(Default)]
133pub enum DataFormat {
134    /// # RDF XML
135    /// Output in [RDF/XML](https://www.w3.org/TR/rdf-syntax-grammar/) format.
136    #[serde(rename = "rdf_xml")]
137    RDFXml,
138    /// # Turtle
139    /// Output in [Turtle](https://www.w3.org/TR/turtle/) format.
140    #[serde(rename = "turtle")]
141    #[default]
142    Turtle,
143    /// # N-Triples
144    /// Output in [N-Triples](https://www.w3.org/TR/n-triples/) format.
145    #[serde(rename = "n_triples")]
146    NTriples,
147    /// # N-Quads
148    /// Output in [N-Quads](https://www.w3.org/TR/n-quads/) format.
149    #[serde(rename = "n_quads")]
150    NQuads,
151}
152
153impl From<&DataFormat> for axone_rdf::serde::DataFormat {
154    fn from(value: &DataFormat) -> Self {
155        match value {
156            DataFormat::RDFXml => Self::RDFXml,
157            DataFormat::Turtle => Self::Turtle,
158            DataFormat::NTriples => Self::NTriples,
159            DataFormat::NQuads => Self::NQuads,
160        }
161    }
162}
163
164/// # StoreLimitsInput
165/// Contains requested limitations regarding store usages.
166#[cw_serde]
167#[derive(Builder)]
168#[builder(default, setter(into, strip_option))]
169pub struct StoreLimitsInput {
170    /// The maximum number of triples the store can contain.
171    /// Default to [Uint128::MAX] if not set, which can be considered as no limit.
172    #[serde(default = "StoreLimitsInput::default_max_triple_count")]
173    pub max_triple_count: Uint128,
174    /// The maximum number of bytes the store can contain.
175    /// The size of a triple is counted as the sum of the size of its subject, predicate and object,
176    /// including the size of data types and language tags if any.
177    /// Default to [Uint128::MAX] if not set, which can be considered as no limit.
178    #[serde(default = "StoreLimitsInput::default_max_byte_size")]
179    pub max_byte_size: Uint128,
180    /// The maximum number of bytes the store can contain for a single triple.
181    /// The size of a triple is counted as the sum of the size of its subject, predicate and object,
182    /// including the size of data types and language tags if any. The limit is used to prevent
183    /// storing very large triples, especially literals.
184    /// Default to [Uint128::MAX] if not set, which can be considered as no limit.
185    #[serde(default = "StoreLimitsInput::default_max_triple_byte_size")]
186    pub max_triple_byte_size: Uint128,
187    /// The maximum limit of a query, i.e. the maximum number of triples returned by a select query.
188    /// Default to 30 if not set.
189    #[serde(default = "StoreLimitsInput::default_max_query_limit")]
190    pub max_query_limit: u32,
191    /// The maximum number of variables a query can select.
192    /// Default to 30 if not set.
193    #[serde(default = "StoreLimitsInput::default_max_query_variable_count")]
194    pub max_query_variable_count: u32,
195    /// The maximum number of bytes an insert data query can contain.
196    /// Default to [Uint128::MAX] if not set, which can be considered as no limit.
197    #[serde(default = "StoreLimitsInput::default_max_insert_data_byte_size")]
198    pub max_insert_data_byte_size: Uint128,
199    /// The maximum number of triples an insert data query can contain (after parsing).
200    /// Default to [Uint128::MAX] if not set, which can be considered as no limit.
201    #[serde(default = "StoreLimitsInput::default_max_insert_data_triple_count")]
202    pub max_insert_data_triple_count: Uint128,
203}
204
205impl StoreLimitsInput {
206    const fn default_max_query_limit() -> u32 {
207        30
208    }
209    const fn default_max_query_variable_count() -> u32 {
210        30
211    }
212    const fn default_max_triple_count() -> Uint128 {
213        Uint128::MAX
214    }
215    const fn default_max_byte_size() -> Uint128 {
216        Uint128::MAX
217    }
218    const fn default_max_triple_byte_size() -> Uint128 {
219        Uint128::MAX
220    }
221    const fn default_max_insert_data_byte_size() -> Uint128 {
222        Uint128::MAX
223    }
224    const fn default_max_insert_data_triple_count() -> Uint128 {
225        Uint128::MAX
226    }
227}
228
229impl Default for StoreLimitsInput {
230    fn default() -> Self {
231        Self {
232            max_triple_count: Self::default_max_triple_count(),
233            max_byte_size: Self::default_max_byte_size(),
234            max_triple_byte_size: Self::default_max_triple_byte_size(),
235            max_query_limit: Self::default_max_query_limit(),
236            max_query_variable_count: Self::default_max_query_variable_count(),
237            max_insert_data_byte_size: Self::default_max_insert_data_byte_size(),
238            max_insert_data_triple_count: Self::default_max_insert_data_triple_count(),
239        }
240    }
241}
242
243/// # StoreResponse
244///
245/// Contains information related to triple store.
246#[cw_serde]
247pub struct StoreResponse {
248    /// The store owner.
249    pub owner: String,
250
251    /// The store limits.
252    pub limits: StoreLimits,
253
254    /// The store current usage.
255    pub stat: StoreStat,
256}
257
258/// # StoreLimits
259/// Contains limitations regarding store usages.
260#[cw_serde]
261#[derive(Default, Builder)]
262#[builder(default, setter(into, strip_option))]
263pub struct StoreLimits {
264    /// The maximum number of triples the store can contain.
265    pub max_triple_count: Uint128,
266
267    /// The maximum number of bytes the store can contain.
268    /// The size of a triple is counted as the sum of the size of its subject, predicate and object,
269    /// including the size of data types and language tags if any.
270    pub max_byte_size: Uint128,
271
272    /// The maximum number of bytes the store can contain for a single triple.
273    /// The size of a triple is counted as the sum of the size of its subject, predicate and object,
274    /// including the size of data types and language tags if any. The limit is used to prevent
275    /// storing very large triples, especially literals.
276    pub max_triple_byte_size: Uint128,
277
278    /// The maximum limit of a query, i.e. the maximum number of triples returned by a select query.
279    pub max_query_limit: u32,
280
281    /// The maximum number of variables a query can select.
282    pub max_query_variable_count: u32,
283
284    /// The maximum number of bytes an insert data query can contain.
285    pub max_insert_data_byte_size: Uint128,
286
287    /// The maximum number of triples an insert data query can contain (after parsing).
288    pub max_insert_data_triple_count: Uint128,
289}
290
291/// # StoreStat
292///
293/// Contains usage information about the triple store.
294#[cw_serde]
295pub struct StoreStat {
296    /// The total number of triple present in the store.
297    pub triple_count: Uint128,
298
299    /// The total number of IRI namespace present in the store.
300    pub namespace_count: Uint128,
301
302    /// The total triple size in the store, in bytes.
303    pub byte_size: Uint128,
304}
305
306/// # IRI
307/// Represents an IRI.
308#[cw_serde]
309pub enum IRI {
310    /// # Prefixed
311    /// An IRI prefixed with a prefix.
312    /// The prefixed IRI is expanded to a full IRI using the prefix definition specified in the query.
313    /// For example, the prefixed IRI `rdf:type` is expanded to `http://www.w3.org/1999/02/22-rdf-syntax-ns#type`.
314    Prefixed(String),
315    /// # Full
316    /// A full IRI.
317    Full(String),
318}
319
320/// # SelectResponse
321/// Represents the response of a [QueryMsg::Select] query.
322#[cw_serde]
323pub struct SelectResponse {
324    /// The head of the response, i.e. the set of variables mentioned in the results.
325    pub head: Head,
326    /// The results of the select query.
327    pub results: Results,
328}
329
330/// # DescribeResponse
331/// Represents the response of a [QueryMsg::Describe] query.
332#[cw_serde]
333pub struct DescribeResponse {
334    /// The format of the data.
335    pub format: DataFormat,
336    /// The data serialized in the specified format.
337    pub data: Binary,
338}
339
340/// # ConstructResponse
341/// Represents the response of a [QueryMsg::Construct] query.
342#[cw_serde]
343pub struct ConstructResponse {
344    /// The format of the data.
345    pub format: DataFormat,
346    /// The data serialized in the specified format.
347    pub data: Binary,
348}
349
350/// # Head
351/// Represents the head of a [SelectResponse].
352#[cw_serde]
353pub struct Head {
354    /// The variables selected in the query.
355    pub vars: Vec<String>,
356}
357
358/// # Results
359/// Represents the results of a [SelectResponse].
360#[cw_serde]
361pub struct Results {
362    /// The bindings of the results.
363    pub bindings: Vec<BTreeMap<String, Value>>,
364}
365
366/// # Value
367#[cw_serde]
368#[serde(tag = "type")]
369pub enum Value {
370    /// # URI
371    /// Represents an IRI.
372    #[serde(rename = "uri")]
373    URI {
374        /// The value of the IRI.
375        value: IRI,
376    },
377    /// # Literal
378    /// Represents a literal S with optional language tag L or datatype IRI D.
379    Literal {
380        /// The value of the literal.
381        value: String,
382        /// The language tag of the literal.
383        #[serde(rename = "xml:lang")]
384        lang: Option<String>,
385        /// The datatype of the literal.
386        datatype: Option<IRI>,
387    },
388    /// # BlankNode
389    /// Represents a blank node.
390    BlankNode {
391        /// The identifier of the blank node.
392        value: String,
393    },
394}
395
396/// # SelectQuery
397/// Represents a SELECT query over the triple store, allowing to select variables to return
398/// and to filter the results.
399#[cw_serde]
400pub struct SelectQuery {
401    /// The prefixes used in the query.
402    pub prefixes: Vec<Prefix>,
403    /// The items to select.
404    /// Note: the number of items to select cannot exceed the maximum query variable count defined
405    /// in the store limitations.
406    pub select: Vec<SelectItem>,
407    /// The WHERE clause.
408    /// If `None`, there is no WHERE clause, i.e. all triples are returned without filtering.
409    pub r#where: WhereClause,
410    /// The maximum number of results to return.
411    /// If `None`, there is no limit.
412    /// Note: the value of the limit cannot exceed the maximum query limit defined in the store
413    /// limitations.
414    pub limit: Option<u32>,
415}
416
417/// # DescribeQuery
418/// Represents a DESCRIBE query over the triple store, allowing to retrieve a description of a resource
419/// as a set of triples serialized in a specific format.
420#[cw_serde]
421pub struct DescribeQuery {
422    /// The prefixes used in the query.
423    pub prefixes: Vec<Prefix>,
424    /// The resource to describe given as a variable or a node.
425    pub resource: VarOrNamedNode,
426    /// The WHERE clause.
427    /// This clause is used to specify the resource identifier to describe using variable bindings.
428    pub r#where: Option<WhereClause>,
429}
430
431/// # ConstructQuery
432/// Represents a CONSTRUCT query over the triple store, allowing to retrieve a set of triples
433/// serialized in a specific format.
434#[cw_serde]
435pub struct ConstructQuery {
436    /// The prefixes used in the query.
437    pub prefixes: Vec<Prefix>,
438    /// The triples to construct.
439    /// If nothing is provided and the `where` clause is a single Bgp, the patterns are used for
440    /// construction.
441    pub construct: Vec<TripleConstructTemplate>,
442    /// The WHERE clause.
443    /// This clause is used to specify the triples to construct using variable bindings.
444    pub r#where: WhereClause,
445}
446
447/// # Prefix
448/// Represents a prefix, i.e. a shortcut for a namespace used in a query.
449#[cw_serde]
450pub struct Prefix {
451    /// The prefix.
452    pub prefix: String,
453    /// The namespace associated with the prefix.
454    pub namespace: String,
455}
456
457/// # SelectItem
458/// Represents an item to select in a [SelectQuery].
459#[cw_serde]
460pub enum SelectItem {
461    /// # Variable
462    /// Represents a variable.
463    Variable(String),
464}
465
466/// # WhereClause
467/// Represents a WHERE clause, i.e. a set of conditions to filter the results.
468#[cw_serde]
469pub enum WhereClause {
470    /// # Bgp
471    /// Represents a basic graph pattern expressed as a set of triple patterns.
472    Bgp { patterns: Vec<TriplePattern> },
473
474    /// # LateralJoin
475    /// Evaluates right for all result row of left
476    LateralJoin { left: Box<Self>, right: Box<Self> },
477
478    /// # Filter
479    /// Filters the inner clause matching the expression.
480    /// The solutions coming from the inner clause that do not match the expression are discarded.
481    /// The variables provided in the inner clause are available in the filter expression.
482    Filter { expr: Expression, inner: Box<Self> },
483}
484
485/// # Expression
486/// Represents a logical combination of operations whose evaluation results in a term.
487#[cw_serde]
488pub enum Expression {
489    /// A named node constant.
490    NamedNode(IRI),
491    /// A literal constant.
492    Literal(Literal),
493    /// A variable that must be bound for evaluation.
494    Variable(String),
495    /// Logical conjunction of expressions.
496    /// All expressions must evaluate to true for the conjunction to be true.
497    /// If the conjunction is empty, it is considered true.
498    And(Vec<Self>),
499    /// Logical disjunction of expressions.
500    /// At least one expression must evaluate to true for the disjunction to be true.
501    /// If the disjunction is empty, it is considered false.
502    Or(Vec<Self>),
503    /// Equality comparison.
504    Equal(Box<Self>, Box<Self>),
505    /// Greater than comparison.
506    Greater(Box<Self>, Box<Self>),
507    /// Greater or equal comparison.
508    GreaterOrEqual(Box<Self>, Box<Self>),
509    /// Less than comparison.
510    Less(Box<Self>, Box<Self>),
511    /// Less or equal comparison.
512    LessOrEqual(Box<Self>, Box<Self>),
513    /// Negation of an expression.
514    Not(Box<Self>),
515}
516
517/// # TripleDeleteTemplate
518/// Represents a triple template to be deleted.
519#[cw_serde]
520pub struct TripleDeleteTemplate {
521    /// The subject of the triple pattern.
522    pub subject: VarOrNamedNode,
523    /// The predicate of the triple pattern.
524    pub predicate: VarOrNamedNode,
525    /// The object of the triple pattern.
526    pub object: VarOrNamedNodeOrLiteral,
527}
528
529/// # TripleConstructTemplate
530/// Represents a triple template to be forged for a construct query.
531#[cw_serde]
532pub struct TripleConstructTemplate {
533    /// The subject of the triple pattern.
534    pub subject: VarOrNode,
535    /// The predicate of the triple pattern.
536    pub predicate: VarOrNamedNode,
537    /// The object of the triple pattern.
538    pub object: VarOrNodeOrLiteral,
539}
540
541/// # TriplePattern
542/// Represents a triple pattern in a [SimpleWhereCondition].
543#[cw_serde]
544pub struct TriplePattern {
545    /// The subject of the triple pattern.
546    pub subject: VarOrNode,
547    /// The predicate of the triple pattern.
548    pub predicate: VarOrNamedNode,
549    /// The object of the triple pattern.
550    pub object: VarOrNodeOrLiteral,
551}
552
553/// # VarOrNode
554/// Represents either a variable or a node.
555#[cw_serde]
556pub enum VarOrNode {
557    /// # Variable
558    /// A variable.
559    Variable(String),
560    /// # Node
561    /// A node, i.e. an IRI or a blank node.
562    Node(Node),
563}
564
565/// # VarOrNamedNode {
566/// Represents either a variable or a named node (IRI).
567#[cw_serde]
568pub enum VarOrNamedNode {
569    /// # Variable
570    /// A variable.
571    Variable(String),
572    /// # NamedNode
573    /// An RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri).
574    NamedNode(IRI),
575}
576
577/// # VarOrNodeOrLiteral
578/// Represents either a variable, a node or a literal.
579#[cw_serde]
580pub enum VarOrNodeOrLiteral {
581    /// # Variable
582    /// A variable.
583    Variable(String),
584    /// # Node
585    /// A node, i.e. an IRI or a blank node.
586    Node(Node),
587    /// # Literal
588    /// An RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal), i.e. a simple literal,
589    /// a language-tagged string or a typed value.
590    Literal(Literal),
591}
592
593/// # VarOrNamedNodeOrLiteral
594/// Represents either a variable, a named node or a literal.
595#[cw_serde]
596pub enum VarOrNamedNodeOrLiteral {
597    /// # Variable
598    /// A variable.
599    Variable(String),
600    /// # NamedNode
601    /// An RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri).
602    NamedNode(IRI),
603    /// # Literal
604    /// An RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal), i.e. a simple literal,
605    /// a language-tagged string or a typed value.
606    Literal(Literal),
607}
608
609/// # Literal
610/// An RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal).
611#[cw_serde]
612pub enum Literal {
613    /// # Simple
614    /// A [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal) without datatype or language form.
615    Simple(String),
616    /// # LanguageTaggedString
617    /// A [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string)
618    LanguageTaggedString {
619        /// The [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form).
620        value: String,
621        /// The [language tag](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tag).
622        language: String,
623    },
624    /// # TypedValue
625    /// A value with a datatype.
626    TypedValue {
627        /// The [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form).
628        value: String,
629        /// The [datatype IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri).
630        datatype: IRI,
631    },
632}
633
634/// # Node
635/// Represents either an IRI (named node) or a blank node.
636#[cw_serde]
637pub enum Node {
638    /// # NamedNode
639    /// An RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri).
640    NamedNode(IRI),
641    /// # BlankNode
642    /// An RDF [blank node](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node).
643    BlankNode(String),
644}
645
646#[cfg(test)]
647mod tests {
648    use crate::msg::{InstantiateMsg, StoreLimitsInput};
649    use cosmwasm_std::Uint128;
650    use schemars::_serde_json;
651
652    #[test]
653    fn store_limit_default_deserialization() {
654        let json = r#"
655          {}
656    "#;
657
658        let input: StoreLimitsInput = _serde_json::from_str(json).unwrap();
659        assert_eq!(input.max_query_limit, 30);
660        assert_eq!(input.max_query_variable_count, 30);
661        assert_eq!(input.max_byte_size, Uint128::MAX);
662        assert_eq!(input.max_triple_count, Uint128::MAX);
663        assert_eq!(input.max_triple_byte_size, Uint128::MAX);
664        assert_eq!(input.max_insert_data_byte_size, Uint128::MAX);
665        assert_eq!(input.max_insert_data_triple_count, Uint128::MAX);
666    }
667
668    #[test]
669    fn instantiate_default_deserialization() {
670        let json = r#"
671          {}
672    "#;
673        let msg: InstantiateMsg = _serde_json::from_str(json).unwrap();
674
675        assert_eq!(msg.limits.max_query_limit, 30);
676        assert_eq!(msg.limits.max_query_variable_count, 30);
677        assert_eq!(msg.limits.max_byte_size, Uint128::MAX);
678        assert_eq!(msg.limits.max_triple_count, Uint128::MAX);
679        assert_eq!(msg.limits.max_triple_byte_size, Uint128::MAX);
680        assert_eq!(msg.limits.max_insert_data_byte_size, Uint128::MAX);
681        assert_eq!(msg.limits.max_insert_data_triple_count, Uint128::MAX);
682    }
683}