1#[macro_use]
2mod macros;
3mod delete;
4mod insert;
5mod select;
6mod update;
7
8use sqlx::database::HasArguments;
9use sqlx::query::{Query, QueryAs};
10use sqlx::{Database, FromRow};
11use std::any::TypeId;
12use std::fmt::Display;
13
14static mut TABLE_PREFIX: String = String::new();
16pub struct TableName {
18 db: String,
19 name: String,
20}
21impl Display for TableName {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23 unsafe { write!(f, "{}{}{}", self.db, TABLE_PREFIX, self.name) }
24 }
25}
26impl SqlQuote<String> for TableName {
27 fn sql_quote(&self) -> String {
28 unsafe { format!("{}{}{}", self.db, TABLE_PREFIX, self.name) }
29 }
30}
31impl TableName {
32 pub fn set_prefix(str: String) {
34 unsafe {
35 TABLE_PREFIX = str;
36 }
37 }
38 pub fn new(name: &str) -> Self {
40 let (db, name) = match name.rfind('.') {
41 Some(index) => name.split_at(index + 1),
42 None => ("", name),
43 };
44 Self {
45 db: db.to_string(),
46 name: name.to_owned(),
47 }
48 }
49 pub fn full_name(&self) -> String {
51 unsafe { format!("{}{}{}", self.db, TABLE_PREFIX, self.name) }
52 }
53}
54#[derive(PartialEq, Eq)]
55pub enum DbType {
56 Mysql,
57 Sqlite,
58 Postgres,
59 MsSql,
60}
61impl DbType {
62 pub fn type_new<DB: sqlx::Database>() -> Self {
63 #[cfg(feature = "sqlx-mysql")]
64 if TypeId::of::<DB>() == TypeId::of::<sqlx::MySql>() {
65 return DbType::Mysql;
66 }
67 #[cfg(feature = "sqlx-sqlite")]
68 if TypeId::of::<DB>() == TypeId::of::<sqlx::Sqlite>() {
69 return DbType::Mysql;
70 }
71 #[cfg(feature = "sqlx-postgres")]
72 if TypeId::of::<DB>() == TypeId::of::<sqlx::Postgres>() {
73 return DbType::Postgres;
74 }
75 #[cfg(feature = "sqlx-mssql")]
76 if TypeId::of::<DB>() == TypeId::of::<sqlx::Mssql>() {
77 return DbType::MsSql;
78 }
79 unimplemented!()
80 }
81 pub fn mark(&self, pos: usize) -> String {
83 match self {
84 DbType::Mysql => "?".to_string(),
85 DbType::Sqlite => {
86 format!("${pos}")
87 }
88 DbType::Postgres => {
89 format!("${}", pos + 1)
90 }
91 DbType::MsSql => "?".to_string(),
92 }
93 }
94}
95
96pub trait ModelTableName {
98 fn table_name() -> TableName;
99}
100pub trait ModelTableField<DB>
102where
103 DB: Database,
104{
105 fn table_pk() -> TableFields;
106 fn table_column() -> TableFields;
107 fn query_sqlx_bind<'t>(
108 &'t self,
109 table_field_val: &FieldItem,
110 res: Query<'t, DB, <DB as HasArguments<'t>>::Arguments>,
111 ) -> Query<'t, DB, <DB as HasArguments<'t>>::Arguments>;
112 fn query_as_sqlx_bind<'t, M>(
113 &'t self,
114 table_field_val: &FieldItem,
115 res: QueryAs<'t, DB, M, <DB as HasArguments<'t>>::Arguments>,
116 ) -> QueryAs<'t, DB, M, <DB as HasArguments<'t>>::Arguments>
117 where
118 for<'r> M: FromRow<'r, DB::Row> + Send + Unpin;
119}
120
121#[derive(Clone, PartialEq, Eq)]
123pub struct FieldItem {
124 pub name: String,
125 pub column_name: String,
126}
127impl Display for FieldItem {
128 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129 write!(f, "{}", self.name)
130 }
131}
132impl FieldItem {
133 pub fn new(name: &str, column_name: &str) -> Self {
134 FieldItem {
135 name: name.to_string(),
136 column_name: column_name.to_string(),
137 }
138 }
139}
140
141pub struct TableFields(Vec<FieldItem>);
143impl Display for TableFields {
144 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145 let fileds = self
146 .0
147 .iter()
148 .map(|e| format!("{e}"))
149 .collect::<Vec<String>>()
150 .join(",");
151 write!(f, "{fileds}")
152 }
153}
154impl TableFields {
155 pub fn new(fields: Vec<FieldItem>) -> Self {
156 TableFields(fields)
157 }
158 pub fn marge(&mut self, field: &[FieldItem]) {
160 for val in field.iter() {
161 if !self.0.iter().any(|e| e.name == val.name) {
162 self.0.push(val.to_owned())
163 }
164 }
165 }
166 pub fn intersect(&mut self, field: &[FieldItem]) {
168 self.0 = self
169 .0
170 .iter()
171 .filter_map(|e| {
172 if field.contains(e) {
173 Some(e.to_owned())
174 } else {
175 None
176 }
177 })
178 .collect();
179 }
180 pub fn del(&mut self, name: &str) {
182 self.0 = self
183 .0
184 .iter()
185 .filter_map(|e| {
186 if name == e.name {
187 None
188 } else {
189 Some(e.to_owned())
190 }
191 })
192 .collect();
193 }
194 pub fn to_vec(&self) -> Vec<String> {
196 let field = self.0.iter();
197 field
198 .map(|e| e.column_name.clone())
199 .collect::<Vec<String>>()
200 }
201}
202
203pub enum WhereOption {
204 None, Where(String), NoWhere(String), }
208
209pub use delete::*;
210pub use insert::*;
211pub use select::*;
212pub use update::*;
213
214use crate::SqlQuote;