1use crate::error::ReflectError;
2use crate::executor::Executor;
3use crate::metadata::{MetaData, Table};
4use crate::options::{ReflectOptions, TableFilter};
5
6impl MetaData {
7 pub async fn reflect<E: Executor>(
8 &mut self,
9 executor: &E,
10 options: &ReflectOptions,
11 ) -> Result<(), ReflectError> {
12 let default_schema = self.schema.clone();
13 let schema = options.schema.as_deref().or(default_schema.as_deref());
14
15 let table_infos = executor
16 .fetch_tables(schema, options.include_views)
17 .await?;
18
19 for info in table_infos {
20 let table_name = info.name.clone();
21
22 if let Some(filter) = &options.only {
24 match filter {
25 TableFilter::Names(names) => {
26 if !names.contains(&table_name) {
27 continue;
28 }
29 }
30 TableFilter::Predicate(pred) => {
31 if !pred(&table_name, self) {
32 continue;
33 }
34 }
35 }
36 }
37
38 let exists = self.tables.contains_key(&table_name);
40 if exists && !options.extend_existing && !options.autoload_replace {
41 continue;
42 }
43
44 let mut table = Table {
45 name: table_name.clone(),
46 schema: schema.map(|s| s.to_string()),
47 columns: Vec::new(),
48 primary_key: None,
49 foreign_keys: Vec::new(),
50 indexes: Vec::new(),
51 is_view: info.is_view,
52 };
53
54 table.columns = executor.fetch_columns(&table_name, schema).await?;
55 table.primary_key = executor.fetch_primary_key(&table_name, schema).await?;
56 if options.resolve_fks {
57 table.foreign_keys = executor.fetch_foreign_keys(&table_name, schema).await?;
58 }
59 table.indexes = executor.fetch_indexes(&table_name, schema).await?;
60
61 if exists && options.extend_existing {
62 if options.autoload_replace {
63 self.tables.insert(table_name.clone(), table);
64 }
65 } else {
66 self.tables.insert(table_name.clone(), table);
67 }
68 }
69
70 Ok(())
71 }
72}