drive/query/drive_document_sum_query/executors/
total.rs1use super::super::index_picker::find_summable_index_for_where_clauses;
9use super::super::{DriveDocumentSumQuery, SumEntry};
10use crate::drive::Drive;
11use crate::error::query::QuerySyntaxError;
12use crate::error::Error;
13use crate::query::WhereClause;
14use dpp::data_contract::document_type::DocumentTypeRef;
15use dpp::version::PlatformVersion;
16use grovedb::TransactionArg;
17
18impl Drive {
19 #[allow(clippy::too_many_arguments)]
27 pub fn execute_document_sum_total_no_proof(
28 &self,
29 contract_id: [u8; 32],
30 document_type: DocumentTypeRef,
31 document_type_name: String,
32 where_clauses: Vec<WhereClause>,
33 sum_property: String,
34 transaction: TransactionArg,
35 platform_version: &PlatformVersion,
36 ) -> Result<Vec<SumEntry>, Error> {
37 use dpp::data_contract::document_type::accessors::{
38 DocumentTypeV0Getters, DocumentTypeV2Getters,
39 };
40
41 if where_clauses.is_empty()
46 && document_type
47 .documents_summable()
48 .map(|p| p == sum_property)
49 .unwrap_or(false)
50 {
51 let sum = self.read_primary_key_sum_tree(
52 &contract_id,
53 &document_type_name,
54 transaction,
55 platform_version,
56 )?;
57 return Ok(vec![SumEntry {
58 in_key: None,
59 key: vec![],
60 sum: Some(sum),
61 }]);
62 }
63
64 let index = find_summable_index_for_where_clauses(
65 document_type.indexes(),
66 &where_clauses,
67 &sum_property,
68 )
69 .ok_or_else(|| {
70 Error::Query(QuerySyntaxError::WhereClauseOnNonIndexedProperty(
71 "sum query requires a `summable: \"<prop>\"` index whose properties \
72 exactly match the where clause fields and whose summed property \
73 matches the request's `sum_property`, or `documentsSummable: \
74 \"<prop>\"` on the document type for unfiltered total sums"
75 .to_string(),
76 ))
77 })?;
78 let sum_query = DriveDocumentSumQuery {
79 document_type,
80 contract_id,
81 document_type_name,
82 index,
83 where_clauses,
84 sum_property,
85 };
86 sum_query.execute_no_proof(self, transaction, platform_version)
87 }
88
89 pub(super) fn read_primary_key_sum_tree(
101 &self,
102 contract_id: &[u8; 32],
103 document_type_name: &str,
104 transaction: TransactionArg,
105 platform_version: &PlatformVersion,
106 ) -> Result<i64, Error> {
107 let drive_version = &platform_version.drive;
108 let path = [
109 &[crate::drive::RootTree::DataContractDocuments as u8] as &[u8],
110 contract_id,
111 &[1u8],
112 document_type_name.as_bytes(),
113 ];
114 let mut drive_operations = vec![];
115 let element = self
116 .grove_get_raw_optional(
117 grovedb_path::SubtreePath::from(path.as_slice()),
118 &[0],
119 crate::util::grove_operations::DirectQueryType::StatefulDirectQuery,
120 transaction,
121 &mut drive_operations,
122 drive_version,
123 )?
124 .ok_or_else(|| {
125 Error::Drive(crate::error::drive::DriveError::CorruptedCodeExecution(
126 "missing primary-key sum tree for an applied document type — \
127 insert_contract_operations_v0 must have created it",
128 ))
129 })?;
130 Ok(element.sum_value_or_default())
131 }
132}