Skip to content

Commit 65babf0

Browse files
committed
Latest updates to the canyon memory process
1 parent 51c81bb commit 65babf0

5 files changed

Lines changed: 75 additions & 88 deletions

File tree

canyon_macros/src/canyon_macro.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use proc_macro2::{Ident, TokenStream};
55

66
use quote::quote;
77

8-
use canyon_observer::QUERIES_TO_EXECUTE;
8+
use canyon_observer::{QUERIES_TO_EXECUTE, CM_QUERIES_TO_EXECUTE};
99
use syn::{Lit, NestedMeta};
1010

1111
#[derive(Debug)]
@@ -107,7 +107,12 @@ fn report_literals_not_allowed(ident: &str, s: &Lit) -> TokenStream1 {
107107
/// Creates a TokenScream that is used to load the data generated at compile-time
108108
/// by the `CanyonManaged` macros again on the queries register
109109
pub fn wire_queries_to_execute(canyon_manager_tokens: &mut Vec<TokenStream>) {
110+
let cm_data = CM_QUERIES_TO_EXECUTE.lock().unwrap();
110111
let data = QUERIES_TO_EXECUTE.lock().unwrap();
112+
113+
let cm_data_to_wire = cm_data.iter().map(|(key, value)| {
114+
quote! { cm_hm.insert(#key, vec![#(#value),*]); }
115+
});
111116
let data_to_wire = data.iter().map(|(key, value)| {
112117
quote! { hm.insert(#key, vec![#(#value),*]); }
113118
});
@@ -116,8 +121,13 @@ pub fn wire_queries_to_execute(canyon_manager_tokens: &mut Vec<TokenStream>) {
116121
use std::collections::HashMap;
117122
use canyon_sql::migrations::processor::MigrationsProcessor;
118123

124+
let mut cm_hm: HashMap<&str, Vec<&str>> = HashMap::new();
119125
let mut hm: HashMap<&str, Vec<&str>> = HashMap::new();
126+
127+
#(#cm_data_to_wire)*;
120128
#(#data_to_wire)*;
129+
130+
MigrationsProcessor::from_query_register(&cm_hm).await;
121131
MigrationsProcessor::from_query_register(&hm).await;
122132
};
123133

canyon_observer/src/constants.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,5 @@
11
pub const NUMERIC_PK_DATATYPE: [&str; 6] = ["i16", "u16", "i32", "u32", "i64", "u64"];
22

3-
pub mod queries {
4-
pub const INSERT_INTO_CANYON_MEMORY: &str =
5-
"INSERT INTO canyon_memory (filepath, struct_name, declared_table_name) \
6-
VALUES ($1, $2, $3)";
7-
pub const UPDATE_CANYON_MEMORY: &str =
8-
"UPDATE canyon_memory SET filepath = $1, struct_name = $2, \
9-
declared_table_name = $3 WHERE id = $4";
10-
pub const DELETE_FROM_CANYON_MEMORY: &str = "DELETE FROM canyon_memory WHERE struct_name = $1";
11-
}
12-
133
pub mod postgresql_queries {
144
pub static CANYON_MEMORY_TABLE: &str = "CREATE TABLE IF NOT EXISTS canyon_memory (
155
id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,

canyon_observer/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,7 @@ pub static CANYON_REGISTER_ENTITIES: Mutex<Vec<CanyonRegisterEntity<'static>>> =
2525
lazy_static! {
2626
pub static ref QUERIES_TO_EXECUTE: Mutex<HashMap<&'static str, Vec<String>>> =
2727
Mutex::new(HashMap::new());
28+
29+
pub static ref CM_QUERIES_TO_EXECUTE: Mutex<HashMap<&'static str, Vec<String>>> =
30+
Mutex::new(HashMap::new());
2831
}

canyon_observer/src/migrations/handler.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,11 @@ impl Migrations {
4949

5050
let canyon_entities = CANYON_REGISTER_ENTITIES.lock().unwrap().to_vec();
5151
let canyon_memory = CanyonMemory::remember(datasource, &canyon_entities).await;
52-
// println!("Canyon memory: {:?}", &canyon_memory);
53-
// println!("Canyon tables: {:?}", &canyon_entities);
5452

5553
// Tracked entities that must be migrated whenever Canyon starts
5654
let schema_status =
5755
Self::fetch_database(datasource.name, datasource.properties.db_type).await;
5856
let database_tables_schema_info = Self::map_rows(schema_status);
59-
// println!("DB tables: {:?}", &database_tables_schema_info);
6057

6158
// We filter the tables from the schema that aren't Canyon entities
6259
let mut user_database_tables = vec![];
@@ -74,14 +71,6 @@ impl Migrations {
7471
}
7572
}
7673

77-
println!(
78-
"Tables to process: {:?}",
79-
user_database_tables
80-
.iter()
81-
.map(|t| &t.table_name)
82-
.collect::<Vec<_>>()
83-
);
84-
8574
migrations_processor
8675
.process(
8776
canyon_memory,

canyon_observer/src/migrations/memory.rs

Lines changed: 61 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::constants;
2-
use canyon_crud::bounds::QueryParameter;
32
use canyon_crud::{bounds::RowOperations, crud::Transaction, DatabaseType, DatasourceConfig};
43
use regex::Regex;
54
use std::collections::HashMap;
@@ -58,6 +57,7 @@ impl Transaction<Self> for CanyonMemory {}
5857
impl CanyonMemory {
5958
/// Queries the database to retrieve internal data about the structures
6059
/// tracked by `CanyonSQL`
60+
#[cfg(not(cargo_check))]
6161
#[allow(clippy::nonminimal_bool)]
6262
pub async fn remember(
6363
datasource: &DatasourceConfig<'static>,
@@ -67,7 +67,6 @@ impl CanyonMemory {
6767
Self::create_memory(datasource.name, &datasource.properties.db_type).await;
6868

6969
// Retrieve the last status data from the `canyon_memory` table
70-
// TODO still pending on the target schema, for now they are created on the default one
7170
let res = Self::query("SELECT * FROM canyon_memory", [], datasource.name)
7271
.await
7372
.expect("Error querying Canyon Memory");
@@ -84,99 +83,71 @@ impl CanyonMemory {
8483
};
8584
db_rows.push(db_row);
8685
}
87-
println!("Data in the canyon_memory table: {db_rows:?}");
8886

8987
// Parses the source code files looking for the #[canyon_entity] annotated classes
9088
let mut mem = Self {
9189
memory: Vec::new(),
9290
renamed_entities: HashMap::new(),
9391
};
9492
Self::find_canyon_entity_annotated_structs(&mut mem, canyon_entities).await;
95-
96-
// Insert into the memory table the new discovered entities
97-
// Care, insert the new ones, delete the olds
98-
// Also, updates the registry when the fields changes
93+
9994
let mut updates = Vec::new();
10095

101-
for _struct in &mem.memory {
102-
// When the filepath and the struct hasn't been modified and are already on db
103-
let already_in_db = db_rows.iter().any(|el| {
104-
(el.filepath == _struct.filepath && el.struct_name == _struct.struct_name)
105-
|| ((el.filepath != _struct.filepath && el.struct_name == _struct.struct_name)
106-
|| (el.filepath == _struct.filepath
107-
&& el.struct_name != _struct.struct_name))
108-
});
109-
if !already_in_db {
110-
match CanyonMemory::query(
111-
constants::queries::INSERT_INTO_CANYON_MEMORY,
112-
[
113-
&_struct.filepath as &dyn QueryParameter,
114-
&_struct.struct_name,
115-
&_struct.declared_table_name,
116-
],
117-
datasource.name,
118-
)
119-
.await
120-
{
121-
Ok(v) => println!("Query insert CM OK: {v:?}"),
122-
Err(e) => println!("Error update CM: {e:?}"),
123-
}
124-
}
96+
for _struct in &mem.memory { // For every program entity detected
97+
let already_in_db = db_rows.iter().find(|el|
98+
el.filepath == _struct.filepath || el.struct_name == _struct.struct_name || el.declared_table_name == _struct.declared_table_name
99+
);
125100

126-
// When the struct or the filepath it's already on db but one of the two has been modified
127-
let need_to_update = db_rows.iter().find(|el| {
128-
(el.filepath == _struct.filepath || el.struct_name == _struct.struct_name)
129-
&& !(el.filepath == _struct.filepath && el.struct_name == _struct.struct_name)
130-
});
101+
if let Some(old) = already_in_db {
102+
if !(old.filepath == _struct.filepath && old.struct_name == _struct.struct_name && old.declared_table_name == _struct.declared_table_name) {
103+
updates.push(old.struct_name);
104+
let stmt = format!(
105+
"UPDATE canyon_memory SET filepath = '{}', struct_name = '{}', declared_table_name = '{}' \
106+
WHERE id = {}",
107+
_struct.filepath, _struct.struct_name, _struct.declared_table_name, old.id
108+
);
109+
save_canyon_memory_query(stmt, datasource.name);
131110

132-
// updated means: the old one. The value to update
133-
if let Some(old) = need_to_update {
134-
updates.push(old.struct_name);
111+
// if the updated element is the struct name, we add it to the table_rename Hashmap
112+
let rename_table = old.declared_table_name != _struct.declared_table_name;
135113

136-
match CanyonMemory::query(
137-
constants::queries::UPDATE_CANYON_MEMORY,
138-
[
139-
&_struct.filepath as &dyn QueryParameter,
140-
&_struct.struct_name,
141-
&_struct.declared_table_name,
142-
&old.id,
143-
],
144-
datasource.name,
145-
)
146-
.await
147-
{
148-
Ok(v) => println!("Query update CM OK: {v:?}"),
149-
Err(e) => println!("Error update CM: {e:?}"),
114+
if rename_table {
115+
mem.renamed_entities.insert(
116+
_struct.declared_table_name.to_string(), // The new one
117+
old.declared_table_name.to_string(), // The old one
118+
);
119+
}
150120
}
121+
}
151122

152-
// if the updated element is the struct name, we add it to the table_rename Hashmap
153-
let rename_table = old.struct_name != _struct.struct_name;
154-
155-
if rename_table {
156-
mem.renamed_entities.insert(
157-
_struct.struct_name.to_string(), // The new one
158-
old.struct_name.to_string(), // The old one
159-
);
160-
}
123+
if already_in_db.is_none() {
124+
println!("\tInsert action for: {_struct:?}");
125+
let stmt = format!(
126+
"INSERT INTO canyon_memory (filepath, struct_name, declared_table_name) \
127+
VALUES ('{}', '{}', '{}')",
128+
_struct.filepath, _struct.struct_name, _struct.declared_table_name
129+
);
130+
save_canyon_memory_query(stmt, datasource.name)
161131
}
162132
}
163133

164-
// Deletes the records when a table is dropped on the previous Canyon run
165-
db_rows.into_iter().for_each(|db_row| {
134+
// Deletes the records from canyon_memory, because they stopped to be tracked by Canyon
135+
for db_row in db_rows.into_iter() {
166136
if !mem
167137
.memory
168138
.iter()
169139
.any(|entity| entity.struct_name == db_row.struct_name)
170140
&& !updates.contains(&db_row.struct_name)
171141
{
172-
// crate::add_cm_query_to_execute(stmt, datasource.name, &[&db_row.struct_name]);
142+
save_canyon_memory_query(format!("DELETE FROM canyon_memory WHERE struct_name = '{}'", db_row.struct_name), datasource.name);
173143
}
174-
});
144+
}
175145
mem
176146
}
177147

178148
/// Parses the Rust source code files to find the one who contains Canyon entities
179149
/// ie -> annotated with `#[canyon_entity]`
150+
#[cfg(not(cargo_check))]
180151
async fn find_canyon_entity_annotated_structs(
181152
&mut self,
182153
canyon_entities: &[CanyonRegisterEntity<'_>],
@@ -234,6 +205,7 @@ impl CanyonMemory {
234205
}
235206

236207
/// Generates, if not exists the `canyon_memory` table
208+
#[cfg(not(cargo_check))]
237209
async fn create_memory(datasource_name: &str, database_type: &DatabaseType) {
238210
let query = if database_type == &DatabaseType::PostgreSql {
239211
constants::postgresql_queries::CANYON_MEMORY_TABLE
@@ -247,6 +219,29 @@ impl CanyonMemory {
247219
}
248220
}
249221

222+
223+
fn save_canyon_memory_query<'a>(stmt: String, ds_name: &'static str) {
224+
use crate::CM_QUERIES_TO_EXECUTE;
225+
226+
if CM_QUERIES_TO_EXECUTE
227+
.lock()
228+
.unwrap()
229+
.contains_key(ds_name)
230+
{
231+
CM_QUERIES_TO_EXECUTE
232+
.lock()
233+
.unwrap()
234+
.get_mut(ds_name)
235+
.unwrap()
236+
.push(stmt);
237+
} else {
238+
CM_QUERIES_TO_EXECUTE
239+
.lock()
240+
.unwrap()
241+
.insert(ds_name, vec![stmt]);
242+
}
243+
}
244+
250245
/// Represents a single row from the `canyon_memory` table
251246
#[derive(Debug)]
252247
struct CanyonMemoryRow<'a> {

0 commit comments

Comments
 (0)