discord_cassandra_cpp/cassandra/schema/
table_meta.rs

1use cassandra_cpp_sys::cass_table_meta_materialized_view;
2use cassandra_cpp_sys::cass_table_meta_materialized_view_by_name_n;
3use cassandra_cpp_sys::cass_table_meta_materialized_view_count;
4
5use crate::cassandra::iterator::ColumnIterator;
6use crate::cassandra::iterator::FieldIterator;
7
8use crate::cassandra::schema::column_meta::ColumnMeta;
9use crate::cassandra::util::{Protected, ProtectedInner};
10use crate::cassandra::value::Value;
11use crate::cassandra_sys::cass_iterator_columns_from_table_meta;
12use crate::cassandra_sys::cass_iterator_fields_from_table_meta;
13use crate::cassandra_sys::cass_table_meta_clustering_key;
14use crate::cassandra_sys::cass_table_meta_clustering_key_count;
15use crate::cassandra_sys::cass_table_meta_column;
16use crate::cassandra_sys::cass_table_meta_column_by_name;
17use crate::cassandra_sys::cass_table_meta_column_count;
18use crate::cassandra_sys::cass_table_meta_field_by_name;
19use crate::cassandra_sys::cass_table_meta_name;
20use crate::cassandra_sys::cass_table_meta_partition_key;
21use crate::cassandra_sys::cass_table_meta_partition_key_count;
22use crate::cassandra_sys::CassTableMeta as _CassTableMeta;
23use std::mem;
24use std::os::raw::c_char;
25use std::slice;
26
27use std::str;
28
29use super::materialized_view_meta::MaterializedViewMeta;
30
31/// Table metadata
32#[derive(Debug)]
33pub struct TableMeta(*const _CassTableMeta);
34
35impl ProtectedInner<*const _CassTableMeta> for TableMeta {
36    fn inner(&self) -> *const _CassTableMeta {
37        self.0
38    }
39}
40
41impl Protected<*const _CassTableMeta> for TableMeta {
42    fn build(inner: *const _CassTableMeta) -> Self {
43        if inner.is_null() {
44            panic!("Unexpected null pointer")
45        };
46        TableMeta(inner)
47    }
48}
49
50impl TableMeta {
51    /// returns an iterator over the fields of this table
52    pub fn field_iter(&mut self) -> FieldIterator {
53        unsafe { FieldIterator::build(cass_iterator_fields_from_table_meta(self.0)) }
54    }
55
56    /// An iterator over the columns in this table
57    pub fn columns_iter(&self) -> ColumnIterator {
58        unsafe { ColumnIterator::build(cass_iterator_columns_from_table_meta(self.0)) }
59    }
60
61    /// Gets the column metadata for the provided column name.
62    pub fn column_by_name(&self, name: &str) -> ColumnMeta {
63        // TODO: can return NULL
64        unsafe {
65            ColumnMeta::build(cass_table_meta_column_by_name(
66                self.0,
67                name.as_ptr() as *const i8,
68            ))
69        }
70    }
71
72    /// Gets the name of the table.
73    pub fn get_name(&self) -> String {
74        unsafe {
75            let mut name = mem::zeroed();
76            let mut name_length = mem::zeroed();
77            cass_table_meta_name(self.0, &mut name, &mut name_length);
78            str::from_utf8(slice::from_raw_parts(
79                name as *const u8,
80                name_length as usize,
81            ))
82            .expect("must be utf8")
83            .to_owned()
84        }
85    }
86
87    /// Gets the total number of columns for the table.
88    pub fn column_count(&self) -> usize {
89        unsafe { cass_table_meta_column_count(self.0) }
90    }
91
92    /// Gets the column metadata for the provided index.
93    pub fn column(&self, index: usize) -> ColumnMeta {
94        // TODO: can return NULL
95        unsafe { ColumnMeta::build(cass_table_meta_column(self.0, index)) }
96    }
97
98    /// Gets the number of columns for the table's partition key.
99    pub fn partition_key_count(&self) -> usize {
100        unsafe { cass_table_meta_partition_key_count(self.0) }
101    }
102
103    /// Gets the partition key column metadata for the provided index.
104    pub fn partition_key(&self, index: usize) -> Option<ColumnMeta> {
105        unsafe {
106            let key = cass_table_meta_partition_key(self.0, index);
107            if key.is_null() {
108                None
109            } else {
110                Some(ColumnMeta::build(key))
111            }
112        }
113    }
114
115    /// Gets the number of columns for the table's clustering key
116    pub fn clustering_key_count(&self) -> usize {
117        unsafe { cass_table_meta_clustering_key_count(self.0) }
118    }
119
120    /// Gets the clustering key column metadata for the provided index.
121    pub fn cluster_key(&self, index: usize) -> Option<ColumnMeta> {
122        unsafe {
123            let key = cass_table_meta_clustering_key(self.0, index);
124            if key.is_null() {
125                None
126            } else {
127                Some(ColumnMeta::build(key))
128            }
129        }
130    }
131
132    /// Gets a metadata field for the provided name. Metadata fields allow direct
133    /// access to the column data found in the underlying "tables" metadata table.
134    pub fn field_by_name(&self, name: &str) -> Option<Value> {
135        // fixme replace CassValue with a custom type
136        unsafe {
137            let value = cass_table_meta_field_by_name(self.0, name.as_ptr() as *const i8);
138            if value.is_null() {
139                None
140            } else {
141                Some(Value::build(value))
142            }
143        }
144    }
145
146    /// Gets the total number of materialized views for the table.
147    pub fn materialized_view_count(&self) -> usize {
148        unsafe { cass_table_meta_materialized_view_count(self.0) }
149    }
150
151    /// Gets the materialized view metadata for the provided index.
152    pub fn materialized_view(&self, index: usize) -> Option<MaterializedViewMeta> {
153        unsafe {
154            let value = cass_table_meta_materialized_view(self.0, index);
155            if value.is_null() {
156                None
157            } else {
158                Some(MaterializedViewMeta::build(value))
159            }
160        }
161    }
162
163    /// Gets the materialized view metadata for the provided name.
164    pub fn materialized_view_by_name(&self, name: &str) -> Option<MaterializedViewMeta> {
165        unsafe {
166            let name_ptr = name.as_ptr() as *const c_char;
167            let value = cass_table_meta_materialized_view_by_name_n(self.0, name_ptr, name.len());
168            if value.is_null() {
169                None
170            } else {
171                Some(MaterializedViewMeta::build(value))
172            }
173        }
174    }
175}