1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use crate::postgres::query_field::{ParameterValueAsRef, QueryWithParamsLoc};
use crate::postgres::static_constant::PARAM_NOTATION;
use crate::error::{Error};
#[derive(Debug)]
pub struct QueryTokens(pub Vec<QueryToken>);
impl QueryTokens {
pub fn build(&self, i: &mut i8) -> Result<QueryWithParamsLoc, Error> {
let mut query = String::from("");
let mut parameters_loc = Vec::new();
{
for wo in &self.0 {
match wo {
QueryToken::Sql(s) => { query.push_str(&s); },
QueryToken::ParameterLoc(p) => {
query.push_str(&format!("{}{}", PARAM_NOTATION, i));
parameters_loc.push(p.clone());
*i += 1;
},
}
}
}
Ok(QueryWithParamsLoc {
query: query,
parameters_loc: parameters_loc,
})
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn push(&mut self, field: QueryToken) {
self.0.push(field);
}
pub fn extend(&mut self, qwhere: QueryTokens) {
self.0.extend(qwhere.0);
}
}
impl Default for QueryTokens {
fn default() -> Self {
QueryTokens(Vec::new())
}
}
#[derive(Debug)]
pub enum QueryToken {
Sql(String),
ParameterLoc(usize),
}
pub struct TmpQueryTokens(pub Vec<TmpQueryToken>);
#[derive(Debug)]
pub enum TmpQueryToken {
Sql(String),
Parameter,
}
impl TmpQueryTokens {
pub fn to_query_tokens(&self, from: usize) -> QueryTokens {
let mut qtokens = QueryTokens::default();
let mut iter = from;
for i in &self.0 {
match i {
TmpQueryToken::Sql(s) => qtokens.push(QueryToken::Sql(s.clone())),
TmpQueryToken::Parameter => {
qtokens.push(QueryToken::ParameterLoc(iter));
iter += 1;
},
}
}
qtokens
}
}
pub type FormatQueryTup<'a> = (TmpQueryTokens, Vec<ParameterValueAsRef<'a>>);
pub fn format_query<S: Into<String>>(query: S, arg: Vec<ParameterValueAsRef>) -> (TmpQueryTokens, Vec<ParameterValueAsRef>) {
let mut argiter = 0;
let mut qtoken: Vec<TmpQueryToken> = Vec::new();
let queryvec: Vec<char> = query.into().chars().collect();
let mut cur: usize = 0;
let mut prevcur: usize = 0;
while cur < queryvec.len() {
if queryvec[cur] == '{' && cur + 1 < queryvec.len() {
if queryvec[cur + 1] == '}' {
if prevcur != cur {
let querypart: String = queryvec[prevcur..cur].iter().cloned().collect();
qtoken.push(TmpQueryToken::Sql(querypart));
}
qtoken.push(TmpQueryToken::Parameter);
argiter += 1;
cur += 2;
prevcur = cur;
}
} else {
cur += 1;
}
}
if prevcur != cur {
let querypart: String = queryvec[prevcur..cur].iter().cloned().collect();
qtoken.push(TmpQueryToken::Sql(querypart));
}
if arg.len() != argiter {
panic!("argument len does not match with query");
}
(TmpQueryTokens(qtoken), arg)
}