cassandra_cpp/cassandra/schema/
keyspace_meta.rs

1use crate::cassandra::data_type::ConstDataType;
2use crate::cassandra::iterator::AggregateIterator;
3use crate::cassandra::iterator::FieldIterator;
4use crate::cassandra::iterator::FunctionIterator;
5use crate::cassandra::iterator::TableIterator;
6use crate::cassandra::iterator::UserTypeIterator;
7use crate::cassandra::schema::aggregate_meta::AggregateMeta;
8
9use crate::cassandra::schema::function_meta::FunctionMeta;
10use crate::cassandra::schema::table_meta::TableMeta;
11use crate::cassandra::util::{Protected, ProtectedInner};
12
13use crate::cassandra_sys::cass_iterator_aggregates_from_keyspace_meta;
14use crate::cassandra_sys::cass_iterator_fields_from_keyspace_meta;
15use crate::cassandra_sys::cass_iterator_functions_from_keyspace_meta;
16use crate::cassandra_sys::CassKeyspaceMeta as _CassKeyspaceMeta;
17use crate::cassandra_sys::CassValue as _CassValue;
18
19use crate::cassandra_sys::cass_iterator_tables_from_keyspace_meta;
20use crate::cassandra_sys::cass_iterator_user_types_from_keyspace_meta;
21use crate::cassandra_sys::cass_keyspace_meta_aggregate_by_name_n;
22use crate::cassandra_sys::cass_keyspace_meta_field_by_name_n;
23use crate::cassandra_sys::cass_keyspace_meta_function_by_name_n;
24use crate::cassandra_sys::cass_keyspace_meta_name;
25use crate::cassandra_sys::cass_keyspace_meta_table_by_name_n;
26use crate::cassandra_sys::cass_keyspace_meta_user_type_by_name_n;
27use crate::cassandra_sys::raw2utf8;
28
29use std::marker::PhantomData;
30
31use std::os::raw::c_char;
32
33/// A snapshot of the schema's metadata.
34//
35// Borrowed immutably.
36#[derive(Debug)]
37pub struct KeyspaceMeta<'a>(*const _CassKeyspaceMeta, PhantomData<&'a _CassKeyspaceMeta>);
38
39impl ProtectedInner<*const _CassKeyspaceMeta> for KeyspaceMeta<'_> {
40    fn inner(&self) -> *const _CassKeyspaceMeta {
41        self.0
42    }
43}
44
45impl Protected<*const _CassKeyspaceMeta> for KeyspaceMeta<'_> {
46    fn build(inner: *const _CassKeyspaceMeta) -> Self {
47        if inner.is_null() {
48            panic!("Unexpected null pointer")
49        };
50        KeyspaceMeta(inner, PhantomData)
51    }
52}
53
54#[derive(Debug)]
55pub struct MetadataFieldValue<'a>(*const _CassValue, PhantomData<&'a _CassValue>);
56
57impl<'a> KeyspaceMeta<'a> {
58    /// Iterator over the aggregates in this keyspace
59    pub fn aggregrates_iter(&self) -> AggregateIterator<'a> {
60        unsafe { AggregateIterator::build(cass_iterator_aggregates_from_keyspace_meta(self.0)) }
61    }
62
63    /// Iterator over the field in this keyspace
64    pub fn fields_iter(&self) -> FieldIterator<'a> {
65        unsafe { FieldIterator::build(cass_iterator_fields_from_keyspace_meta(self.0)) }
66    }
67
68    /// Gets the table metadata for the provided table name.
69    pub fn table_by_name(&self, name: &str) -> Option<TableMeta<'a>> {
70        unsafe {
71            let name_ptr = name.as_ptr() as *const c_char;
72            let value = cass_keyspace_meta_table_by_name_n(self.0, name_ptr, name.len());
73            if value.is_null() {
74                None
75            } else {
76                Some(TableMeta::build(value))
77            }
78        }
79    }
80
81    /// Gets the data type for the provided type name.
82    pub fn user_type_by_name(&self, name: &str) -> Option<ConstDataType<'a>> {
83        unsafe {
84            let name_ptr = name.as_ptr() as *const c_char;
85            let value = cass_keyspace_meta_user_type_by_name_n(self.0, name_ptr, name.len());
86            if value.is_null() {
87                None
88            } else {
89                Some(ConstDataType::build(value))
90            }
91        }
92    }
93
94    /// Gets the function metadata for the provided function name.
95    pub fn get_function_by_name(
96        &self,
97        name: &str,
98        arguments: Vec<&str>,
99    ) -> Option<FunctionMeta<'a>> {
100        unsafe {
101            let name_ptr = name.as_ptr() as *const c_char;
102            let arguments_str = arguments.join(",");
103            let arguments_ptr = arguments_str.as_ptr() as *const c_char;
104            let value = cass_keyspace_meta_function_by_name_n(
105                self.0,
106                name_ptr,
107                name.len(),
108                arguments_ptr,
109                arguments_str.len(),
110            );
111            if value.is_null() {
112                None
113            } else {
114                Some(FunctionMeta::build(value))
115            }
116        }
117    }
118
119    /// Gets the aggregate metadata for the provided aggregate name.
120    pub fn aggregate_by_name(&self, name: &str, arguments: Vec<&str>) -> Option<AggregateMeta<'a>> {
121        unsafe {
122            let name_ptr = name.as_ptr() as *const c_char;
123            let arguments_str = arguments.join(",");
124            let arguments_ptr = arguments_str.as_ptr() as *const c_char;
125            let agg = cass_keyspace_meta_aggregate_by_name_n(
126                self.0,
127                name_ptr,
128                name.len(),
129                arguments_ptr,
130                arguments_str.len(),
131            );
132            if agg.is_null() {
133                None
134            } else {
135                Some(AggregateMeta::build(agg))
136            }
137        }
138    }
139
140    /// Iterator over the tables in this keyspaces
141    pub fn table_iter(&self) -> TableIterator<'a> {
142        unsafe { TableIterator::build(cass_iterator_tables_from_keyspace_meta(self.0)) }
143    }
144
145    /// Iterator over the functions in this keyspaces
146    pub fn function_iter(&self) -> FunctionIterator<'a> {
147        unsafe { FunctionIterator::build(cass_iterator_functions_from_keyspace_meta(self.0)) }
148    }
149
150    /// Iterator over the UDTs in this keyspaces
151    pub fn user_type_iter(&self) -> UserTypeIterator<'a> {
152        unsafe { UserTypeIterator::build(cass_iterator_user_types_from_keyspace_meta(self.0)) }
153    }
154
155    /// Gets the name of the keyspace.
156    pub fn name(&self) -> String {
157        let mut name = std::ptr::null();
158        let mut name_length = 0;
159        unsafe {
160            cass_keyspace_meta_name(self.0, &mut name, &mut name_length);
161            raw2utf8(name, name_length).expect("must be utf8")
162        }
163    }
164
165    /// Gets a metadata field for the provided name. Metadata fields allow direct
166    /// access to the column data found in the underlying "keyspaces" metadata table.
167    pub fn field_by_name(&self, name: &str) -> Option<MetadataFieldValue<'a>> {
168        unsafe {
169            let name_ptr = name.as_ptr() as *const c_char;
170            let value = cass_keyspace_meta_field_by_name_n(self.0, name_ptr, name.len());
171            if value.is_null() {
172                None
173            } else {
174                Some(MetadataFieldValue(value, PhantomData))
175            }
176        }
177    }
178}