realm_db_reader/
group.rs

1use tracing::{instrument, warn};
2
3use crate::array::{Array, ArrayStringShort};
4use crate::error::TableError;
5use crate::table::Table;
6use crate::traits::ArrayLike;
7
8/// The group is the central root of a Realm database. It contains all the
9/// tables and their names.
10///
11/// The main way to interact with the Realm database, is by opening the
12/// [`Realm`](crate::Realm::open), and calling
13/// [`realm.into_group`][`crate::Realm::into_group`]. The resulting [`Group`]
14/// can then be used to access tables.
15///
16/// ```no_run
17/// use realm_db_reader::{Realm, Group};
18///
19/// let realm = Realm::open("example.realm").unwrap();
20/// let group = realm.into_group().unwrap();
21///
22/// let table = group.get_table(0).unwrap();
23/// let row = table.get_row(0).unwrap();
24/// ```
25#[derive(Debug)]
26pub struct Group {
27    tables_array: Array,
28    table_names: Vec<String>,
29}
30
31impl Group {
32    #[instrument(level = "debug")]
33    pub(crate) fn build(array: Array) -> crate::RealmResult<Self> {
34        let table_names = {
35            let array: ArrayStringShort = array.get_node(0)?.unwrap();
36            array.get_all()?
37        };
38
39        let tables_array = array.get_node(1)?.unwrap();
40
41        Ok(Self {
42            tables_array,
43            table_names,
44        })
45    }
46}
47
48impl Group {
49    /// Get the [`Table`] with the given number (starting from 0).
50    ///
51    /// Panics if the table number is out of bounds.
52    #[instrument(level = "debug", skip(self), fields(table_names = ?self.table_names))]
53    pub fn get_table(&self, table_number: usize) -> crate::TableResult<Table> {
54        let table_array = self.tables_array.get_node(table_number)?.unwrap();
55
56        let table = Table::build(table_array, table_number)?;
57
58        Ok(table)
59    }
60
61    /// Get the [`Table`] with the given name.
62    ///
63    /// Panics if the table name is not found.
64    #[instrument(level = "debug", skip(self), fields(table_names = ?self.table_names))]
65    pub fn get_table_by_name(&self, name: &str) -> crate::TableResult<Table> {
66        let table_number = self
67            .table_names
68            .iter()
69            .position(|n| n == name)
70            .ok_or_else(|| TableError::TableNotFound {
71                name: name.to_string(),
72            })?;
73
74        self.get_table(table_number)
75    }
76
77    /// Get the number of tables in the group.
78    pub fn table_count(&self) -> usize {
79        self.table_names.len()
80    }
81
82    /// Get the name of the table at the given index.
83    ///
84    /// Panics if the index is out of bounds.
85    pub fn get_table_name(&self, index: usize) -> &str {
86        &self.table_names[index]
87    }
88
89    /// Get the names of all tables in the group.
90    pub fn get_table_names(&self) -> &[String] {
91        &self.table_names
92    }
93}