oracle_sql_tools/lib.rs
1#![doc = include_str!("../README.md")]
2
3use oracle::Connection;
4
5use statements::{PreppedGridData, PreppedRowData};
6use format_data::{FormatData, FormattedData};
7use types::DatatypeIndexes;
8
9pub mod statements;
10pub mod types;
11pub mod utils;
12pub mod format_data;
13
14/// A trait to prepare either a vector or a 2-dimensional vector for a SQL query
15///
16/// The trait either returns [`statements::PreppedRowData`] or [`statements::PreppedGridData`] respectively
17///
18/// Using a vector to select specific columns from a table:
19///
20/// ```no_run
21/// let conn: oracle::Connection = match Connection::connect("<USERNAME>", "<PASSWORD>", "<IP ADDRESS>")?;
22///
23/// let col_names: Vec<&str> = vec!["Employee ID", "Name", "Job Title", "Department", "Business Unit"];
24///
25/// let table_data: Vec<Vec<Option<String>>> = col_names.prep_data(conn).select("MY_TABLE")?;
26/// ```
27///
28/// Using a 2-dimensional vector to insert data:
29///
30/// ```no_run
31/// let conn: oracle::Connection = match Connection::connect("<USERNAME>", "<PASSWORD>", "<IP ADDRESS>")?;
32///
33/// let data: Vec<Vec<String>> = vec![
34/// vec!["ColA".to_string(), "ColB".to_string(), "ColC".to_string()],
35/// vec!["A1".to_string(), "B1".to_string(), "C1".to_string()],
36/// vec!["A2".to_string(), "B2".to_string(), "C2".to_string()],
37/// vec!["A3".to_string(), "B3".to_string(), "C3".to_string()],
38/// ];
39///
40/// data.prep_data(conn).insert("MY_TABLE")?;
41/// Ok(())
42/// ```
43pub trait PrepData<T: FormatData> {
44 type Prep;
45
46 fn prep_data(self, connection: Connection) -> Self::Prep;
47}
48
49impl<T: FormatData> PrepData<T> for Vec<Vec<T>> {
50 type Prep = PreppedGridData;
51
52 fn prep_data(self, connection: Connection) -> Self::Prep {
53 // get's the 'dominate' datatype from each column
54 // weighted in order: VARCHAR2, FLOAT, INT, DATE
55 let mut is_varchar: Vec<usize> = Vec::new();
56 let mut is_float: Vec<usize> = Vec::new();
57 let mut is_int: Vec<usize> = Vec::new();
58 let mut is_date: Vec<usize> = Vec::new();
59
60 let mut data = Vec::new();
61 let mut y_index: usize = 0 as usize;
62 for row in self {
63 let mut inner_vec = Vec::new();
64 let mut x_index: usize = 0 as usize;
65 for cell in row {
66 let formatted_cell = cell.fmt_data();
67 if y_index > 0 {
68 match &formatted_cell {
69 FormattedData::STRING(_) => is_varchar.push(x_index),
70 FormattedData::INT(_) => is_int.push(x_index),
71 FormattedData::FLOAT(_) => is_float.push(x_index),
72 FormattedData::DATE(_) => is_date.push(x_index),
73 FormattedData::TIMESTAMP(_) => is_date.push(x_index),
74 FormattedData::EMPTY => {
75 inner_vec.push(formatted_cell);
76 x_index += 1 as usize;
77 continue;
78 },
79 }
80 }
81 inner_vec.push(formatted_cell);
82 x_index += 1 as usize;
83 }
84 data.push(inner_vec);
85 y_index += 1 as usize;
86 }
87
88 let data_indexes = DatatypeIndexes {
89 is_varchar,
90 is_float,
91 is_int,
92 is_date,
93 }.find_uniques();
94
95 Self::Prep {
96 data,
97 conn: connection,
98 data_indexes
99 }
100 }
101}
102
103impl<T: FormatData> PrepData<T> for Vec<T> {
104 type Prep = PreppedRowData;
105
106 fn prep_data(self, connection: Connection) -> Self::Prep {
107 let mut data = Vec::new();
108 for val in self { data.push(val.fmt_data().to_string()) }
109 Self::Prep {
110 data,
111 conn: connection,
112 }
113 }
114}