drive/query/drive_document_count_query/executors/
total.rs1use super::super::super::conditions::WhereClause;
5use super::super::{DriveDocumentCountQuery, SplitCountEntry};
6use crate::drive::Drive;
7use crate::error::query::QuerySyntaxError;
8use crate::error::Error;
9use dpp::data_contract::document_type::DocumentTypeRef;
10use dpp::version::PlatformVersion;
11use grovedb::TransactionArg;
12
13impl Drive {
14 pub fn execute_document_count_total_no_proof(
22 &self,
23 contract_id: [u8; 32],
24 document_type: DocumentTypeRef,
25 document_type_name: String,
26 where_clauses: Vec<WhereClause>,
27 transaction: TransactionArg,
28 platform_version: &PlatformVersion,
29 ) -> Result<Vec<SplitCountEntry>, Error> {
30 use dpp::data_contract::document_type::accessors::{
31 DocumentTypeV0Getters, DocumentTypeV2Getters,
32 };
33
34 if where_clauses.is_empty() && document_type.documents_countable() {
39 let count = self.read_primary_key_count_tree(
40 &contract_id,
41 &document_type_name,
42 transaction,
43 platform_version,
44 )?;
45 return Ok(vec![SplitCountEntry {
46 in_key: None,
47 key: vec![],
48 count: Some(count),
53 }]);
54 }
55
56 let index = DriveDocumentCountQuery::find_countable_index_for_where_clauses(
57 document_type.indexes(),
58 &where_clauses,
59 )
60 .ok_or_else(|| {
61 Error::Query(QuerySyntaxError::WhereClauseOnNonIndexedProperty(
62 "count query requires a `countable: true` index whose properties \
63 exactly match the where clause fields, or `documentsCountable: \
64 true` on the document type for unfiltered total counts"
65 .to_string(),
66 ))
67 })?;
68 let count_query = DriveDocumentCountQuery {
69 document_type,
70 contract_id,
71 document_type_name,
72 index,
73 where_clauses,
74 };
75 count_query.execute_no_proof(self, transaction, platform_version)
76 }
77
78 pub(super) fn read_primary_key_count_tree(
90 &self,
91 contract_id: &[u8; 32],
92 document_type_name: &str,
93 transaction: TransactionArg,
94 platform_version: &PlatformVersion,
95 ) -> Result<u64, Error> {
96 let drive_version = &platform_version.drive;
97 let path = [
98 &[crate::drive::RootTree::DataContractDocuments as u8] as &[u8],
99 contract_id,
100 &[1u8],
101 document_type_name.as_bytes(),
102 ];
103 let mut drive_operations = vec![];
104 let element = self.grove_get_raw_optional(
105 grovedb_path::SubtreePath::from(path.as_slice()),
106 &[0],
107 crate::util::grove_operations::DirectQueryType::StatefulDirectQuery,
108 transaction,
109 &mut drive_operations,
110 drive_version,
111 )?;
112 Ok(element.map_or(0, |e| e.count_value_or_default()))
113 }
114}