Skip to content

Commit b2b6ea0

Browse files
committed
♻️ refactor: extract Statement and Portal into dedicated modules
- Extract Statement struct and impl into context/statement.rs (44 lines) - Extract Portal enum and impl into context/portal.rs (68 lines) - Remove ~110 lines from context/mod.rs main file - Add public re-exports for backward compatibility - Clean up unused imports and formatting This modular organization improves: - Code maintainability with focused single-responsibility modules - Context module readability by reducing main file complexity - Developer experience with logical separation of concerns - Architecture consistency following established patterns All existing functionality preserved with proper import handling.
1 parent aecdbeb commit b2b6ea0

File tree

3 files changed

+115
-109
lines changed

3 files changed

+115
-109
lines changed

packages/cipherstash-proxy/src/postgresql/context/mod.rs

Lines changed: 3 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
pub mod column;
2+
pub mod portal;
3+
pub mod statement;
24

5+
pub use self::{portal::Portal, statement::Statement};
36
use super::{
47
column_mapper::ColumnMapper,
5-
format_code::FormatCode,
68
messages::{describe::Describe, Name, Target},
79
Column,
810
};
@@ -98,26 +100,6 @@ pub struct Queue<T> {
98100
pub queue: VecDeque<T>,
99101
}
100102

101-
///
102-
/// Type Analysed parameters and projection
103-
///
104-
#[derive(Debug, Clone, PartialEq)]
105-
pub struct Statement {
106-
pub param_columns: Vec<Option<Column>>,
107-
pub projection_columns: Vec<Option<Column>>,
108-
pub literal_columns: Vec<Option<Column>>,
109-
pub postgres_param_types: Vec<i32>,
110-
}
111-
112-
#[derive(Clone, Debug)]
113-
pub enum Portal {
114-
Encrypted {
115-
format_codes: Vec<FormatCode>,
116-
statement: Arc<Statement>,
117-
},
118-
Passthrough,
119-
}
120-
121103
impl Context {
122104
pub fn new(
123105
client_id: i32,
@@ -684,38 +666,6 @@ impl Context {
684666
}
685667
}
686668

687-
impl Statement {
688-
pub fn new(
689-
param_columns: Vec<Option<Column>>,
690-
projection_columns: Vec<Option<Column>>,
691-
literal_columns: Vec<Option<Column>>,
692-
postgres_param_types: Vec<i32>,
693-
) -> Statement {
694-
Statement {
695-
param_columns,
696-
projection_columns,
697-
literal_columns,
698-
postgres_param_types,
699-
}
700-
}
701-
702-
pub fn unencryped() -> Statement {
703-
Statement::new(vec![], vec![], vec![], vec![])
704-
}
705-
706-
pub fn has_literals(&self) -> bool {
707-
!self.literal_columns.is_empty()
708-
}
709-
710-
pub fn has_params(&self) -> bool {
711-
!self.param_columns.is_empty()
712-
}
713-
714-
pub fn has_projection(&self) -> bool {
715-
!self.projection_columns.is_empty()
716-
}
717-
}
718-
719669
impl<T> Queue<T> {
720670
pub fn new() -> Self {
721671
Queue {
@@ -736,62 +686,6 @@ impl<T> Queue<T> {
736686
}
737687
}
738688

739-
impl Portal {
740-
pub fn encrypted_with_format_codes(
741-
statement: Arc<Statement>,
742-
format_codes: Vec<FormatCode>,
743-
) -> Portal {
744-
Portal::Encrypted {
745-
statement,
746-
format_codes,
747-
}
748-
}
749-
750-
pub fn encrypted(statement: Arc<Statement>) -> Portal {
751-
let format_codes = vec![];
752-
Portal::Encrypted {
753-
statement,
754-
format_codes,
755-
}
756-
}
757-
758-
pub fn passthrough() -> Portal {
759-
Portal::Passthrough
760-
}
761-
762-
pub fn projection_columns(&self) -> &Vec<Option<Column>> {
763-
static EMPTY: Vec<Option<Column>> = vec![];
764-
match self {
765-
Portal::Encrypted { statement, .. } => &statement.projection_columns,
766-
_ => &EMPTY,
767-
}
768-
}
769-
770-
// FormatCodes should not be None at this point
771-
// FormatCodes will be:
772-
// - empty, in which case assume Text
773-
// - single value, in which case use this for all columns
774-
// - multiple values, in which case use the value for each column
775-
pub fn format_codes(&self, row_len: usize) -> Vec<FormatCode> {
776-
match self {
777-
Portal::Encrypted { format_codes, .. } => match format_codes.len() {
778-
0 => vec![FormatCode::Text; row_len],
779-
1 => {
780-
let format_code = match format_codes.first() {
781-
Some(code) => *code,
782-
None => FormatCode::Text,
783-
};
784-
vec![format_code; row_len]
785-
}
786-
_ => format_codes.clone(),
787-
},
788-
Portal::Passthrough => {
789-
unreachable!()
790-
}
791-
}
792-
}
793-
}
794-
795689
#[cfg(test)]
796690
mod tests {
797691
use super::{Context, Describe, KeysetIdentifier, Portal, Statement};
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use super::{super::format_code::FormatCode, Column};
2+
use crate::postgresql::context::statement::Statement;
3+
use std::sync::Arc;
4+
5+
#[derive(Clone, Debug)]
6+
pub enum Portal {
7+
Encrypted {
8+
format_codes: Vec<FormatCode>,
9+
statement: Arc<Statement>,
10+
},
11+
Passthrough,
12+
}
13+
14+
impl Portal {
15+
pub fn encrypted_with_format_codes(
16+
statement: Arc<Statement>,
17+
format_codes: Vec<FormatCode>,
18+
) -> Portal {
19+
Portal::Encrypted {
20+
statement,
21+
format_codes,
22+
}
23+
}
24+
25+
pub fn encrypted(statement: Arc<Statement>) -> Portal {
26+
let format_codes = vec![];
27+
Portal::Encrypted {
28+
statement,
29+
format_codes,
30+
}
31+
}
32+
33+
pub fn passthrough() -> Portal {
34+
Portal::Passthrough
35+
}
36+
37+
pub fn projection_columns(&self) -> &Vec<Option<Column>> {
38+
static EMPTY: Vec<Option<Column>> = vec![];
39+
match self {
40+
Portal::Encrypted { statement, .. } => &statement.projection_columns,
41+
_ => &EMPTY,
42+
}
43+
}
44+
45+
// FormatCodes should not be None at this point
46+
// FormatCodes will be:
47+
// - empty, in which case assume Text
48+
// - single value, in which case use this for all columns
49+
// - multiple values, in which case use the value for each column
50+
pub fn format_codes(&self, row_len: usize) -> Vec<FormatCode> {
51+
match self {
52+
Portal::Encrypted { format_codes, .. } => match format_codes.len() {
53+
0 => vec![FormatCode::Text; row_len],
54+
1 => {
55+
let format_code = match format_codes.first() {
56+
Some(code) => *code,
57+
None => FormatCode::Text,
58+
};
59+
vec![format_code; row_len]
60+
}
61+
_ => format_codes.clone(),
62+
},
63+
Portal::Passthrough => {
64+
unreachable!()
65+
}
66+
}
67+
}
68+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use super::Column;
2+
3+
///
4+
/// Type Analysed parameters and projection
5+
///
6+
#[derive(Debug, Clone, PartialEq)]
7+
pub struct Statement {
8+
pub param_columns: Vec<Option<Column>>,
9+
pub projection_columns: Vec<Option<Column>>,
10+
pub literal_columns: Vec<Option<Column>>,
11+
pub postgres_param_types: Vec<i32>,
12+
}
13+
14+
impl Statement {
15+
pub fn new(
16+
param_columns: Vec<Option<Column>>,
17+
projection_columns: Vec<Option<Column>>,
18+
literal_columns: Vec<Option<Column>>,
19+
postgres_param_types: Vec<i32>,
20+
) -> Statement {
21+
Statement {
22+
param_columns,
23+
projection_columns,
24+
literal_columns,
25+
postgres_param_types,
26+
}
27+
}
28+
29+
pub fn unencryped() -> Statement {
30+
Statement::new(vec![], vec![], vec![], vec![])
31+
}
32+
33+
pub fn has_literals(&self) -> bool {
34+
!self.literal_columns.is_empty()
35+
}
36+
37+
pub fn has_params(&self) -> bool {
38+
!self.param_columns.is_empty()
39+
}
40+
41+
pub fn has_projection(&self) -> bool {
42+
!self.projection_columns.is_empty()
43+
}
44+
}

0 commit comments

Comments
 (0)