Advertisement
Guest User

Untitled

a guest
May 3rd, 2019
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.60 KB | None | 0 0
  1. #[macro_use]
  2. pub mod query_builder {
  3. //! SQL like generic query builder.
  4. //! 構文木の生成までを行うので、それをトラバースして必要な処理を行う。
  5.  
  6. use std::rc::Rc;
  7. use std::fmt::Debug;
  8. use std::marker::PhantomData;
  9.  
  10. /// Entityのフィールドを表す型が実装するメソッド
  11. pub trait Field: Debug {
  12. /// 演算子の右辺の型
  13. type Data: Debug;
  14. }
  15.  
  16. /// クエリ全体を表すtrait。単なるマーク。
  17. pub trait Query<P, O>: Debug {
  18. fn walk(&self) -> O;
  19. }
  20.  
  21. #[derive(Debug)]
  22. pub struct BoxedQuery<P, O> {
  23. pub query: Rc<Query<P, O>>,
  24. }
  25.  
  26. // impl<P, O> Query<P, O> for BoxedQuery<P, O> {}
  27.  
  28. impl<P, O> BoxedQuery<P, O> {
  29. fn new<Q: Query<P, O> + 'static>(query: Q) -> BoxedQuery<P, O> {
  30. BoxedQuery {
  31. query: Rc::new(query),
  32. }
  33. }
  34. }
  35.  
  36. #[derive(Debug, Clone, PartialEq, Eq)]
  37. pub struct And<P, O, Q1: Query<P, O>, Q2: Query<P, O>>(pub Q1, pub Q2, PhantomData<P>, PhantomData<O>);
  38. // impl<P, O, Q1: Query<P, O>, Q2: Query<P, O>> Query<P, O> for And<P, O, Q1, Q2> {}
  39.  
  40. impl<P, O, T, S> And<P, O, T, S>
  41. where
  42. T: Query<P, O>,
  43. S: Query<P, O>,
  44. {
  45. pub fn new(l: T, r: S) -> And<P, O, T, S> {
  46. And(l, r, PhantomData, PhantomData)
  47. }
  48. }
  49.  
  50. impl<P, O, T, S> And<P, O, T, S>
  51. where
  52. T: Query<P, O>,
  53. S: Query<P, O>,
  54. Self: Query<P, O>,
  55. {
  56. pub fn and<Q: Query<P, O>>(self, rhs: Q) -> And<P, O, Self, Q> {
  57. And::new(self, rhs)
  58. }
  59. }
  60.  
  61. impl<P, O, T, S> And<P, O, T, S>
  62. where
  63. P: 'static,
  64. O: 'static,
  65. T: Query<P, O> + 'static,
  66. S: Query<P, O> + 'static,
  67. Self: Query<P, O>,
  68. {
  69. pub fn into_boxed(self) -> BoxedQuery<P, O> {
  70. BoxedQuery::new(self)
  71. }
  72. }
  73.  
  74. #[derive(Debug, Clone, PartialEq, Eq)]
  75. pub struct Or<P, O, T: Query<P, O>, S: Query<P, O>>(pub T, pub S, PhantomData<P>, PhantomData<O>);
  76. // impl<P, O, T: Query<P, O>, S: Query<P, O>> Query<P, O> for Or<P, O, T, S> {}
  77.  
  78. impl<P, O, T, S> Or<P, O, T, S>
  79. where
  80. T: Query<P, O>,
  81. S: Query<P, O>,
  82. {
  83. pub fn new(l: T, r: S) -> Or<P, O, T, S> {
  84. Or(l, r, PhantomData, PhantomData)
  85. }
  86. }
  87.  
  88. impl<P, O, T: Query<P, O>, S: Query<P, O>> Or<P, O, T, S>
  89. where
  90. T: Query<P, O>,
  91. S: Query<P, O>,
  92. Self: Query<P, O>,
  93. {
  94. pub fn or<Q: Query<P,O>>(self, rhs: Q) -> Or<P, O, Self, Q> {
  95. Or::new(self, rhs)
  96. }
  97. }
  98.  
  99. impl<P, O, T: Query<P, O> + 'static, S: Query<P, O> + 'static> Or<P, O, T, S>
  100. where
  101. P: 'static,
  102. O: 'static,
  103. T: Query<P, O> + 'static,
  104. S: Query<P, O> + 'static,
  105. Self: Query<P, O>,
  106. {
  107. pub fn into_boxed(self) -> BoxedQuery<P, O> {
  108. BoxedQuery::new(self)
  109. }
  110. }
  111.  
  112. #[derive(Debug, Clone, PartialEq, Eq)]
  113. pub struct Not<P, O, T: Query<P, O>>(pub T, PhantomData<P>, PhantomData<O>);
  114. // impl<P, O, T: Query<P, O>> Query<P,O> for Not<P, O, T> {}
  115.  
  116. pub fn not<P, O, T: Query<P,O>>(q: T) -> Not<P, O, T> {
  117. Not(q, PhantomData, PhantomData)
  118. }
  119.  
  120. impl<P, O, T> Not<P, O, T>
  121. where
  122. T: Query<P, O>,
  123. Self: Query<P, O>,
  124. {
  125. pub fn and<Q: Query<P, O>>(self, rhs: Q) -> And<P, O, Self, Q> {
  126. And::new(self, rhs)
  127. }
  128.  
  129. pub fn or<Q: Query<P, O>>(self, rhs: Q) -> Or<P, O, Self, Q> {
  130. Or::new(self, rhs)
  131. }
  132. }
  133.  
  134. impl<P, O, T> Not<P, O, T>
  135. where
  136. P: 'static,
  137. O: 'static,
  138. T: Query<P, O> + 'static,
  139. Self: Query<P, O>,
  140. {
  141. pub fn into_boxed(self) -> BoxedQuery<P, O> {
  142. BoxedQuery::new(self)
  143. }
  144. }
  145.  
  146. #[derive(Debug, Clone)]
  147. pub enum Operator<T: Field> {
  148. /// `==`
  149. Eq(T, T::Data),
  150. /// `!=`
  151. NotEq(T, T::Data),
  152. /// `>`
  153. Gt(T, T::Data),
  154. /// `>=`
  155. Ge(T, T::Data),
  156. /// `<`
  157. Lt(T, T::Data),
  158. /// `<=`
  159. Le(T, T::Data),
  160. /// Like SQL `between`
  161. Between(T, T::Data, T::Data),
  162. /// Like SQL `like`
  163. Like(T, T::Data),
  164. Any(T, Vec<T::Data>),
  165. NotAny(T, Vec<T::Data>),
  166. }
  167. // impl<P, O, T: Field + Debug + 'static> Query<P, O> for Operator<T> {}
  168.  
  169. impl<T> Operator<T>
  170. where
  171. T: Field + Debug + 'static,
  172. {
  173. pub fn and<P, O, Q>(self, rhs: Q) -> And<P, O, Self, Q>
  174. where
  175. Q: Query<P, O>,
  176. Self: Query<P, O>,
  177. {
  178. And::new(self, rhs)
  179. }
  180.  
  181. pub fn or<P, O, Q>(self, rhs: Q) -> Or<P, O, Self, Q>
  182. where
  183. Q: Query<P, O>,
  184. Self: Query<P, O>,
  185. {
  186. Or::new(self, rhs)
  187. }
  188.  
  189. pub fn into_boxed<P, O>(self) -> BoxedQuery<P, O>
  190. where
  191. Self: Query<P, O>,
  192. {
  193. BoxedQuery::new(self)
  194. }
  195. }
  196.  
  197. /// Entityのfield型に生やすメソッド。演算子。
  198. pub trait OperatorMethod: Field + Sized {
  199. /// `==`
  200. fn eq(self, rhs: Self::Data) -> Operator<Self> {
  201. Operator::Eq(self, rhs)
  202. }
  203.  
  204. /// `!=`
  205. fn not_eq(self, rhs: Self::Data) -> Operator<Self> {
  206. Operator::NotEq(self, rhs)
  207. }
  208.  
  209. /// `>`
  210. fn gt(self, rhs: Self::Data) -> Operator<Self> {
  211. Operator::Gt(self, rhs)
  212. }
  213.  
  214. /// `>=`
  215. fn ge(self, rhs: Self::Data) -> Operator<Self> {
  216. Operator::Ge(self, rhs)
  217. }
  218.  
  219. /// `<`
  220. fn lt(self, rhs: Self::Data) -> Operator<Self> {
  221. Operator::Lt(self, rhs)
  222. }
  223.  
  224. /// `<=`
  225. fn le(self, rhs: Self::Data) -> Operator<Self> {
  226. Operator::Le(self, rhs)
  227. }
  228.  
  229. /// Like SQL `between`
  230. fn between(self, from: Self::Data, until: Self::Data) -> Operator<Self> {
  231. Operator::Between(self, from, until)
  232. }
  233.  
  234. /// Like SQL `like`
  235. fn like(self, rhs: Self::Data) -> Operator<Self> {
  236. Operator::Like(self, rhs)
  237. }
  238.  
  239. fn any(self, rhs: Vec<Self::Data>) -> Operator<Self> {
  240. Operator::Any(self, rhs)
  241. }
  242.  
  243. fn not_any(self, rhs: Vec<Self::Data>) -> Operator<Self> {
  244. Operator::NotAny(self, rhs)
  245. }
  246. }
  247.  
  248. #[macro_export]
  249. macro_rules! query_info {
  250. ( $( @ $item:item )* $name:ident { $( $field:ident : $field_type:ty ),* $(,)* } ) => {
  251. pub mod $name {
  252. pub mod query {
  253. use crate::query_builder::*;
  254.  
  255. $( $item )*
  256.  
  257. $(
  258. #[allow(dead_code, non_camel_case_types)]
  259. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
  260. pub struct $field;
  261.  
  262. impl Field for $field {
  263. type Data = $field_type;
  264. }
  265.  
  266. impl OperatorMethod for $field {}
  267. )*
  268. }
  269. }
  270. }
  271. }
  272. }
  273.  
  274. mod entity {
  275. use chrono::prelude::*;
  276.  
  277. pub trait FieldName {
  278. fn name(&self) -> &str;
  279. }
  280.  
  281. macro_rules! impl_field_name {
  282. ( $( $field:ty > $name:tt ),* $(,)* ) => {
  283. $(
  284. impl FieldName for $field {
  285. fn name(&self) -> &str {
  286. $name
  287. }
  288. }
  289. )*
  290. }
  291. }
  292.  
  293. #[derive(Debug)]
  294. pub struct User {
  295. pub id: u64,
  296. pub id_name: String,
  297. pub display_name: String,
  298. pub password: String,
  299. pub status: u8,
  300. pub created_at: DateTime<Utc>,
  301. pub updated_at: DateTime<Utc>,
  302. }
  303.  
  304. query_info! {
  305. @use chrono::prelude::*;
  306. @use failure::Error;
  307.  
  308. user {
  309. id: u64,
  310. id_name: String,
  311. display_name: String,
  312. password: String,
  313. status: u8,
  314. created_at: DateTime<Utc>,
  315. updated_at: DateTime<Utc>,
  316. }
  317. }
  318.  
  319. impl_field_name!(
  320. self::user::query::id > "id",
  321. self::user::query::id_name > "id_name",
  322. self::user::query::display_name > "display_name",
  323. self::user::query::password > "password",
  324. self::user::query::status > "status",
  325. self::user::query::created_at > "created_at",
  326. self::user::query::updated_at > "updated_at",
  327. );
  328.  
  329. pub struct User2 {
  330. pub id: u64,
  331. pub id_name: String,
  332. pub display_name: String,
  333. pub password: String,
  334. pub status: u8,
  335. pub created_at: DateTime<Utc>,
  336. pub updated_at: DateTime<Utc>,
  337. }
  338.  
  339. query_info! {
  340. @use chrono::prelude::*;
  341.  
  342. user2 {
  343. id: u64,
  344. id_name: String,
  345. display_name: String,
  346. password: String,
  347. status: u8,
  348. created_at: DateTime<Utc>,
  349. updated_at: DateTime<Utc>,
  350. }
  351. }
  352.  
  353. impl_field_name!(
  354. self::user2::query::id > "id",
  355. self::user2::query::id_name > "id_name",
  356. self::user2::query::display_name > "display_name",
  357. self::user2::query::password > "password",
  358. self::user2::query::status > "status",
  359. self::user2::query::created_at > "created_at",
  360. self::user2::query::updated_at > "updated_at",
  361. );
  362. }
  363.  
  364. mod repository {
  365. pub mod user {
  366. //! ストレージ上での格納形式に対応する型はここで定義。
  367.  
  368. use crate::entity::{FieldName, User};
  369. use crate::query_builder::{And, Field, Not, Operator, Or, Query, BoxedQuery};
  370. use failure::bail;
  371. use std::fmt::Display;
  372.  
  373. pub struct Repository;
  374.  
  375. impl Repository {
  376. // 複数entityに対してはtraitを使った型による条件分岐が必要。
  377. pub fn search<Q>(&self, query: Q) -> Result<Vec<User>, failure::Error>
  378. where
  379. Q: Query<StringProcessor, String>,
  380. {
  381. println!("Build: {}", query.walk());
  382. bail!("hoge")
  383. }
  384. }
  385.  
  386. pub trait Processor<T> {
  387. type Input;
  388. type Output;
  389.  
  390. fn process(input: &Self::Input) -> Self::Output;
  391. }
  392.  
  393. #[derive(Debug)]
  394. pub struct StringProcessor;
  395.  
  396. impl<T> Processor<Operator<T>> for StringProcessor
  397. where
  398. T: Field + FieldName,
  399. T::Data: Display,
  400. {
  401. type Input = Operator<T>;
  402. type Output = String;
  403.  
  404. fn process(input: &Operator<T>) -> String {
  405. use itertools::join;
  406. match input {
  407. Operator::Eq(field, rhs) => format!("{} = {}", field.name(), rhs),
  408. Operator::NotEq(field, rhs) => format!("{} != {}", field.name(), rhs),
  409. Operator::Gt(field, rhs) => format!("{} > {}", field.name(), rhs),
  410. Operator::Ge(field, rhs) => format!("{} >= {}", field.name(), rhs),
  411. Operator::Lt(field, rhs) => format!("{} < {}", field.name(), rhs),
  412. Operator::Le(field, rhs) => format!("{} <= {}", field.name(), rhs),
  413. Operator::Between(field, from, until) => {
  414. format!("{} between {} and {}", field.name(), from, until)
  415. }
  416. Operator::Like(field, rhs) => format!("{} like '{}'", field.name(), rhs),
  417. Operator::Any(field, rhs) => format!("{} in ({})", field.name(), join(rhs.iter(), ", ")),
  418. Operator::NotAny(field, rhs) => format!("{} like ({})", field.name(), join(rhs.iter(), ", ")),
  419. }
  420. }
  421. }
  422.  
  423. impl<Q1, Q2> Processor<And<StringProcessor, String, Q1, Q2>> for StringProcessor
  424. where
  425. Q1: Query<StringProcessor, String>,
  426. Q2: Query<StringProcessor, String>,
  427. {
  428. type Input = (String, String);
  429. type Output = String;
  430.  
  431. fn process(input: &(String, String)) -> String {
  432. format!("({}) and ({})", input.0, input.1)
  433. }
  434. }
  435.  
  436. impl<Q1, Q2> Processor<Or<StringProcessor, String, Q1, Q2>> for StringProcessor
  437. where
  438. Q1: Query<StringProcessor, String>,
  439. Q2: Query<StringProcessor, String>,
  440. {
  441. type Input = (String, String);
  442. type Output = String;
  443.  
  444. fn process(input: &(String, String)) -> String {
  445. format!("({}) or ({})", input.0, input.1)
  446. }
  447. }
  448.  
  449. impl<Q1> Processor<Not<StringProcessor, String, Q1>> for StringProcessor
  450. where
  451. Q1: Query<StringProcessor, String>,
  452. {
  453. type Input = String;
  454. type Output = String;
  455.  
  456. fn process(input: &String) -> Steing {
  457. format!("not ({})", input)
  458. }
  459. }
  460.  
  461. impl<T> Query<StringProcessor, String> for Operator<T>
  462. where
  463. T: Field + FieldName,
  464. T::Data: Display,
  465. {
  466. fn walk(&self) -> String {
  467. <StringProcessor as Processor<Self>>::process(self)
  468. }
  469. }
  470.  
  471. impl<Q1, Q2> Query<StringProcessor, String> for And<StringProcessor, String, Q1, Q2>
  472. where
  473. Q1: Query<StringProcessor, String>,
  474. Q2: Query<StringProcessor, String>,
  475. {
  476. fn walk(&self) -> String {
  477. <StringProcessor as Processor<Self>>::process(&(self.0.walk(), self.1.walk()))
  478. }
  479. }
  480.  
  481. impl<Q1, Q2> Query<StringProcessor, String> for Or<StringProcessor, String, Q1, Q2>
  482. where
  483. Q1: Query<StringProcessor, String>,
  484. Q2: Query<StringProcessor, String>,
  485. {
  486. fn walk(&self) -> String {
  487. <StringProcessor as Processor<Self>>::process(&(self.0.walk(), self.1.walk()))
  488. }
  489. }
  490.  
  491. impl<Q1> Query<StringProcessor, String> for Not<StringProcessor, String, Q1>
  492. where
  493. Q1: Query<StringProcessor, String>,
  494. {
  495. fn walk(&self) -> String {
  496. <StringProcessor as Processor<Self>>::process(&self.0.walk())
  497. }
  498. }
  499.  
  500. impl Query<StringProcessor, String> for BoxedQuery<StringProcessor, String>
  501. {
  502. fn walk(&self) -> String {
  503. self.query.as_ref().walk()
  504. }
  505. }
  506. }
  507. }
  508.  
  509. fn main() -> Result<(), failure::Error> {
  510. use crate::entity::user2::query::*;
  511. use crate::query_builder::*;
  512. use crate::repository;
  513. use chrono::prelude::*;
  514.  
  515. println!("===== static query =====");
  516. let query = id
  517. .eq(32)
  518. .and(created_at.eq(Utc::now()).or(updated_at.eq(Utc::now())));
  519. let query = display_name.like("foo".into()).or(query);
  520. println!("{:?}", query);
  521. let _ = repository::user::Repository.search(query);
  522. let _ = repository::user::Repository.search(status.eq(1));
  523.  
  524. println!("===== dynamic query =====");
  525. let mut query = id.eq(1).and(id.eq(2)).into_boxed();
  526. if rand::random::<u8>() < 127 {
  527. query = created_at.eq(Utc::now()).or(query).into_boxed();
  528. }
  529. query = And::new(
  530. updated_at.eq(Utc::now()),
  531. if rand::random::<u8>() % 2 == 0 {
  532. status.eq(1).or(query).into_boxed()
  533. } else {
  534. status.eq(2).or(query).into_boxed()
  535. }
  536. ).and(id_name.any(vec!["yamada".into(), "satoh".into()])).into_boxed();
  537. println!("{:?}", query);
  538. let _ = repository::user::Repository.search(query);
  539.  
  540. Ok(())
  541. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement