sqlite_diff_rs/schema/
simple_table.rs1use alloc::string::String;
8use alloc::vec;
9use alloc::vec::Vec;
10use core::hash::{Hash, Hasher};
11
12use crate::parser::TableSchema;
13use crate::{encoding::Value, schema::dyn_table::IndexableValues};
14
15use super::{DynTable, SchemaWithPK};
16
17#[derive(Debug, Clone, Eq)]
34pub struct SimpleTable {
35 schema: TableSchema<String>,
37 columns: Vec<String>,
39}
40
41impl SimpleTable {
42 #[must_use]
54 pub fn new(name: impl Into<String>, columns: &[&str], pk_indices: &[usize]) -> Self {
55 let name = name.into();
56 let columns: Vec<String> = columns.iter().map(|&c| String::from(c)).collect();
57 let column_count = columns.len();
58
59 let mut pk_flags = vec![0u8; column_count];
61 for (pk_ordinal, &col_idx) in pk_indices.iter().enumerate() {
62 assert!(col_idx < column_count, "PK index out of bounds");
63 pk_flags[col_idx] = u8::try_from(pk_ordinal + 1).expect("Too many PK columns");
64 }
65
66 Self {
67 schema: TableSchema::new(name, column_count, pk_flags),
68 columns,
69 }
70 }
71
72 #[must_use]
74 pub fn column_names(&self) -> &[String] {
75 &self.columns
76 }
77
78 #[must_use]
80 pub fn column_name(&self, index: usize) -> Option<&str> {
81 self.columns.get(index).map(String::as_str)
82 }
83
84 #[must_use]
86 pub fn column_index(&self, name: &str) -> Option<usize> {
87 self.columns.iter().position(|c| c == name)
88 }
89
90 #[must_use]
92 pub fn pk_indices(&self) -> Vec<usize> {
93 self.schema.pk_indices()
94 }
95
96 #[must_use]
98 pub fn inner(&self) -> &TableSchema<String> {
99 &self.schema
100 }
101}
102
103impl PartialEq for SimpleTable {
104 fn eq(&self, other: &Self) -> bool {
105 self.schema == other.schema && self.columns == other.columns
106 }
107}
108
109impl Hash for SimpleTable {
110 fn hash<H: Hasher>(&self, state: &mut H) {
111 self.schema.hash(state);
112 self.columns.hash(state);
113 }
114}
115
116impl DynTable for SimpleTable {
117 #[inline]
118 fn name(&self) -> &str {
119 self.schema.name()
120 }
121
122 #[inline]
123 fn number_of_columns(&self) -> usize {
124 self.schema.number_of_columns()
125 }
126
127 #[inline]
128 fn write_pk_flags(&self, buf: &mut [u8]) {
129 self.schema.write_pk_flags(buf);
130 }
131}
132
133impl SchemaWithPK for SimpleTable {
134 fn number_of_primary_keys(&self) -> usize {
135 self.schema.number_of_primary_keys()
136 }
137
138 fn primary_key_index(&self, col_idx: usize) -> Option<usize> {
139 self.schema.primary_key_index(col_idx)
140 }
141
142 fn extract_pk<S, B>(
143 &self,
144 values: &impl IndexableValues<Text = S, Binary = B>,
145 ) -> alloc::vec::Vec<Value<S, B>>
146 where
147 S: Clone,
148 B: Clone,
149 {
150 self.schema.extract_pk(values)
151 }
152}
153
154pub trait NamedColumns: SchemaWithPK {
157 fn column_index(&self, column_name: &str) -> Option<usize>;
161}
162
163impl NamedColumns for SimpleTable {
164 #[inline]
165 fn column_index(&self, column_name: &str) -> Option<usize> {
166 self.column_index(column_name)
167 }
168}
169
170impl<T: NamedColumns> NamedColumns for &T {
171 #[inline]
172 fn column_index(&self, column_name: &str) -> Option<usize> {
173 T::column_index(self, column_name)
174 }
175}