Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Ejercicio individual | (75.42) Taller de programación I

## Alumno: Testa Santiago Tomas ( 108301 )

### Detalles de entrega

El trabajo no se encuentra completo.

Pendientes:

1. Funcionalidad: Logica booleana en WHERE

2. Funcionalidad: SELECT c/ ORDER BY

3. Funcionalidad: DELETE

4. Funcionalidad: UPDATE

5. Testing (mas test unitarios e integración)

6. Cargo clippy sin warnings

7. Documentación de funciones

Funcionalidades probadas OK

1. SELECT * FROM

2. SELECT columnas FROM

3. SELECT c/ WHERE

4. INSERT INTO

### Detalles de implementación

Para la lógica booleana el objetivo era crear un arbol de condiciones formado por las relaciones de precedencia.

Dicho objetivo no pudo ser implementado. Se implementó lógica de condiciones simples ( no compuestas )
46 changes: 46 additions & 0 deletions src/condition.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
pub mod condition_type;
/*
pub mod complex_condition;

use crate::libs::error;
use condition_type::BooleanOperator;
*/

use condition_type::ConditionOperator;

pub struct Condition {
pub condition: ConditionOperator,
pub column: Option<String>,
pub value: Option<String>,
}

pub fn build_condition(column: String, value: String, cond: ConditionOperator) -> Condition {
Condition {
condition: cond,
column: Some(column),
value: Some(value),
}
}

pub fn operate_condition(v1: &String, v2: &String, operator: &ConditionOperator ) -> bool {
if let Ok(x1) = v1.parse::<i32>() {
if let Ok(x2) = v2.parse::<i32>() {
match operator {
ConditionOperator::Minor => return x1 < x2,
ConditionOperator::MinorEqual => return x1 <= x2,
ConditionOperator::Equal => return x1 == x2,
ConditionOperator::Higher => return x1 > x2,
ConditionOperator::HigherEqual => return x1 >= x2,
}
};
};

match operator {
ConditionOperator::Minor => true,
ConditionOperator::MinorEqual => true,
ConditionOperator::Equal => v1.eq(v2),
ConditionOperator::Higher => true,
ConditionOperator::HigherEqual => true,
}
}

166 changes: 166 additions & 0 deletions src/condition/complex_condition.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
use crate::query::Query;
use crate::libs::error;
use super::BooleanOperator;

pub struct ComplexCondition {
// Tree of complex conditions
pub operator: Option<BooleanOperator>,
pub condition: Option<BooleanOperator>,
pub left_cond: Option<Box<ComplexCondition>>, // Oldest condition ( first to be found )
pub right_cond: Option<Box<ComplexCondition>> // Newest condition ( last to be found )
}

pub fn build_empty_complex_condition() -> ComplexCondition {
return ComplexCondition {
operator: None,
condition: None,
left_cond: None,
right_cond: None
}
}

pub fn build_complex_condition(operator: BooleanOperator, left: Option<Box<ComplexCondition>>, right: Option<Box<ComplexCondition>>) -> ComplexCondition {
return ComplexCondition {
operator: Some(operator),
condition: None,
left_cond: left,
right_cond: right
}
}

pub fn tree_check(root: ComplexCondition) -> bool {
// In Order valid check ( no None leafs )
match &root.operator {
Some(op) => {
match op {
BooleanOperator::OR => tree_check_or_and(root),
BooleanOperator::AND => tree_check_or_and(root),
BooleanOperator::NOT => tree_check_not(root)
}
},
None => return true
}
}

fn tree_check_or_and(root: ComplexCondition) -> bool {
match root.left_cond {
Some(left) => {
match root.right_cond {
Some(right) => return tree_check(*left) && tree_check(*right),
None => return false
}
},
None => return false
}
}

fn tree_check_not(root: ComplexCondition) -> bool {
match root.left_cond {
Some(left) => {
match root.right_cond {
Some(_) => return false,
None => return tree_check(*left)
}
},
None => return false
}
}

pub fn add_node_to_tree(args: &Vec<String>, start_position: &mut usize, root: ComplexCondition) -> Result<ComplexCondition,u32> {
if *start_position == args.len() || args[*start_position].eq("ORDER") {
if tree_check(root) {
Ok(root)
} else {
Err(error::WHERE_MAL_FORMATEADO)
}
} else if args[*start_position].eq("OR") {
add_node_to_tree_or(args, &mut start_position, root)
} else if args[*start_position].eq("AND") {
add_node_to_tree_and(args, &mut start_position, root)
} else if args[*start_position].eq("NOT") {
add_node_to_tree_not(args, &mut start_position, root)
} else if check_valid_args_for_basic_condition(args, *start_position) {
match root.operator {
Some(op) => {

},
None => return Err(error::WHERE_MAL_FORMATEADO) // C1 C2
}
} else {
Err(error::WHERE_MAL_FORMATEADO)
}
}

fn add_node_to_tree_or(args: &Vec<String>, start_position: &mut usize, root: ComplexCondition) -> Result<ComplexCondition,u32> {
let new_root = build_complex_condition(BooleanOperator::OR, Some(Box::new(root)), None );
*start_position += 1;
add_node_to_tree(args, start_position, new_root)
}

fn add_node_to_tree_and(args: &Vec<String>, start_position: &mut usize, root: ComplexCondition) -> Result<ComplexCondition,u32> {
match root.operator {
Some(op) => {
match op {
BooleanOperator::OR => {
match root.left_cond {
Some(x) => {},
None => return Err(error::WHERE_MAL_FORMATEADO)
}
},
BooleanOperator::AND => {
let new_root = build_complex_condition(BooleanOperator::AND, Some(Box::new(root)), None );
*start_position += 1;
add_node_to_tree(args, start_position , new_root)
},
BooleanOperator::NOT => {
let new_root = build_complex_condition(BooleanOperator::AND, Some(Box::new(root)), None );
*start_position += 1;
add_node_to_tree(args, start_position, new_root)
},
}
},
None => {
let new_root = build_complex_condition(BooleanOperator::AND, Some(Box::new(root)), None );
*start_position += 1;
add_node_to_tree(args, start_position, new_root)
}
}
}

fn add_node_to_tree_not(args: &Vec<String>, start_position: &mut usize, root: ComplexCondition) -> Result<ComplexCondition,u32> {

}

fn check_valid_args_for_basic_condition(args: &Vec<String>, start_position: usize) -> bool {
if start_position + 3 > args.len() {
false
} else {
let first = &args[start_position];
let second = &args[start_position + 1];
let third = &args[start_position + 2];

if first.eq("AND") || first.eq("OR") || first.eq("NOT") {
false
} else if second.eq("AND") || second.eq("OR") || second.eq("NOT") {
false
} else if ! ( second.eq(">") || second.eq(">=") || second.eq("=") || second.eq("<") || second.eq("<=") ) {
false
} else if third.eq("AND") || third.eq("OR") || third.eq("NOT") {
false
} else {
true
}
}
}

pub fn get_where_columns(query: &Query, vec: Vec<String>, node: &ComplexCondition) -> Vec<String> {
match node.operator {
Some(_) => {},
None => {
match node.condition {
Some(_) => {},
None => return vec
}
}
}
}
13 changes: 13 additions & 0 deletions src/condition/condition_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
pub enum ConditionOperator {
Minor, // Int
MinorEqual, // Int
Equal, // Int and String
Higher, // Int
HigherEqual, // Int
}

pub enum BooleanOperator {
AND,
OR,
NOT,
}
4 changes: 4 additions & 0 deletions src/libs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Dumb file for organize everything into libs
pub mod error;
pub mod exec;
pub mod parsing;
17 changes: 17 additions & 0 deletions src/libs/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
pub static OPERACION_INVALIDA: u32 = 1;
pub static DELETE_MAL_FORMATEADO: u32 = 2;
pub static INSERT_MAL_FORMATEADO: u32 = 3;
pub static SELECT_MAL_FORMATEADO: u32 = 4;
pub static UPDATE_MAL_FORMATEADO: u32 = 5;
pub static ARCHIVO_NO_PUDO_SER_ABIERTO: u32 = 6;
pub static ARCHIVO_VACIO: u32 = 7;
pub static ARCHIVO_NO_CONTIENE_COLUMNAS_SOLICITADAS: u32 = 8;
pub static WHERE_EN_DELETE_MAL_FORMATEADO: u32 = 9;
pub static WHERE_MAL_FORMATEADO: u32 = 10;
pub static ORDER_BY_MAL_FORMATEADO: u32 = 11;
pub static NO_WHERE: u32 = 12;

pub fn print_err(error_code: u32) {
// TODO print error
println!("ERROR. Codigo: {}", error_code)
}
Loading