Browse Source

Misc bugfixes, doc updates

master
Timothy Warren 2 months ago
parent
commit
eb838306ec
6 changed files with 233 additions and 88 deletions
  1. 3
    1
      src/drivers.rs
  2. 18
    12
      src/drivers/postgres.rs
  3. 1
    6
      src/lib.rs
  4. 205
    60
      src/query_builder.rs
  5. 3
    6
      src/types.rs
  6. 3
    3
      tests/integration_test.rs

+ 3
- 1
src/drivers.rs View File

@@ -102,7 +102,9 @@ pub trait DatabaseDriver {
102 102
     }
103 103
 
104 104
     // Runs a basic sql query on the database
105
-    // fn query(&self, sql: &str) -> Result<impl Any, impl Error>;
105
+    fn query(&self, sql: &str) -> Result<Box<dyn Any>, Box<dyn Any>> {
106
+        Ok(Box::new(String::from(sql)))
107
+    }
106 108
 
107 109
     /// Prepares an sql statement for the database
108 110
     fn prepare(&self, sql: &str) -> Result<(), ()> {

+ 18
- 12
src/drivers/postgres.rs View File

@@ -33,18 +33,6 @@ impl PostgresDriver {
33 33
 
34 34
         self.connection = RefCell::new(Some(connection));
35 35
     }
36
-
37
-    pub fn query(&self, sql: &str) -> Result<Vec<Row>, Error> {
38
-        if self.connection.borrow().is_none() {
39
-            panic!("No database connection.");
40
-        }
41
-
42
-        self.connection
43
-            .borrow_mut()
44
-            .as_mut()
45
-            .unwrap()
46
-            .query(sql, &[])
47
-    }
48 36
 }
49 37
 
50 38
 impl DatabaseDriver for PostgresDriver {
@@ -55,4 +43,22 @@ impl DatabaseDriver for PostgresDriver {
55 43
     fn random(&self) -> String {
56 44
         String::from(" RANDOM()")
57 45
     }
46
+
47
+    fn query(&self, sql: &str) -> Result<Box<dyn Any>, Box<dyn Any>> {
48
+        if self.connection.borrow().is_none() {
49
+            panic!("No database connection.");
50
+        }
51
+
52
+        let result = self
53
+            .connection
54
+            .borrow_mut()
55
+            .as_mut()
56
+            .unwrap()
57
+            .query(sql, &[]);
58
+
59
+        match result {
60
+            Ok(res) => Ok(Box::new(res)),
61
+            Err(e) => Err(Box::new(e)),
62
+        }
63
+    }
58 64
 }

+ 1
- 6
src/lib.rs View File

@@ -35,12 +35,7 @@ pub mod prelude {
35 35
     //! This includes enum types, traits,
36 36
     //! the Query Builder, and individual database drivers.
37 37
     pub use crate::drivers::DatabaseDriver;
38
-    pub use crate::query_builder::{
39
-        JoinType,
40
-        LikeWildcard,
41
-        OrderDirection,
42
-        QueryBuilder,
43
-    };
38
+    pub use crate::query_builder::{JoinType, LikeWildcard, OrderDirection, QueryBuilder};
44 39
 
45 40
     #[cfg(feature = "postgres")]
46 41
     /// Postgres Driver

+ 205
- 60
src/query_builder.rs View File

@@ -79,7 +79,36 @@ enum QueryType {
79 79
     Delete,
80 80
 }
81 81
 
82
-/// The struct representing a query builder
82
+/// QueryBuilder for general SQL queries
83
+///
84
+/// ```
85
+/// use stringqb::prelude::*;
86
+///
87
+/// // You probably do not want to use the default driver, as it
88
+/// // is basically a mock for testing
89
+/// use stringqb::drivers::DefaultDriver;
90
+///
91
+/// // The query builder must be mutable to be useful
92
+/// let mut qb = QueryBuilder::new(DefaultDriver::new());
93
+///
94
+/// // Each builder method returns a mutable reference to itself so
95
+/// // the methods are chainable
96
+/// qb.select("field as f")
97
+///     .from("table t")
98
+///     .inner_join("table_two tt", "field2 as ff", "=", "f")
99
+///     .wher("f >", 3);
100
+///
101
+/// // Since they are references, you do not have to chain.
102
+/// let sql = qb.get_compiled_select();
103
+///
104
+/// # assert_eq!(
105
+/// #    sql,
106
+/// #    r#"SELECT "field" AS "f"
107
+/// FROM "table" "t"
108
+/// INNER JOIN "table_two" "tt" ON "field2" AS "ff"=f
109
+/// WHERE "f" > ?"#
110
+/// # );
111
+/// ```
83 112
 pub struct QueryBuilder {
84 113
     /// The struct to store the query builder info
85 114
     state: QueryState,
@@ -87,9 +116,7 @@ pub struct QueryBuilder {
87 116
 }
88 117
 
89 118
 /// The struct representing a prepared statement
90
-pub struct Prepared {
91
-
92
-}
119
+pub struct Prepared {}
93 120
 
94 121
 impl Default for QueryBuilder {
95 122
     /// Creates a new QueryBuilder instance with default driver
@@ -109,19 +136,19 @@ impl QueryBuilder {
109 136
     /// ```no_run
110 137
     /// use stringqb::prelude::*;
111 138
     ///
112
-    /// // You probably do not want to use the default driver, as it
113
-    /// // is basically a mock for testing
114
-    /// use stringqb::drivers::DefaultDriver;
139
+    /// // Postgres Driver (If enabled)
140
+    /// let pgDriver = PostgresDriver::new("postgres://");
115 141
     ///
116
-    /// // The query builder must be mutable to be useful
117
-    /// let mut qb = QueryBuilder::new(DefaultDriver::new());
142
+    /// #[cfg(feature = "sqlite")]
143
+    /// // SQLite Driver (memory)
144
+    /// let liteMemoryDriver = SQLiteDriver::new(":memory:");
118 145
     ///
119
-    /// // Each builder method returns a mutable reference to itself so
120
-    /// // the methods are chainable
121
-    /// qb.select("field f").from("table");
146
+    /// #[cfg(feature = "sqlite")]
147
+    /// // SQLite Driver (file)
148
+    /// let liteDriver = SQLiteDriver::new("/path/to/db.sqlite3");
122 149
     ///
123
-    /// // Since they are references, you do not have to chain.
124
-    /// let sql = qb.get_compiled_select();
150
+    /// // The variable to the query builder must be mutable
151
+    /// let mut queryBuilder = QueryBuilder::new(pgDriver);
125 152
     /// ```
126 153
     pub fn new(driver: impl DatabaseDriver + 'static) -> Self {
127 154
         QueryBuilder {
@@ -137,28 +164,13 @@ impl QueryBuilder {
137 164
     /// Set the fields to select from the database as a string
138 165
     ///
139 166
     /// ```no_run
140
-    /// # let mut qb = stringqb::query_builder::QueryBuilder::default();
167
+    /// # use stringqb::prelude::*;
168
+    /// # let mut qb = QueryBuilder::default();
141 169
     /// // You can also alias field names
142 170
     /// qb.select("foo as bar");
143 171
     /// ```
144 172
     pub fn select(&mut self, fields: &str) -> &mut Self {
145
-        lazy_static! {
146
-            static ref RE: Regex = Regex::new(r"(?i) as ").unwrap();
147
-        };
148
-
149
-        let fields = split_map_join(fields, ",", |s| {
150
-            if !RE.is_match(s) {
151
-                return self.driver.quote_identifier(s.trim());
152
-            }
153
-
154
-            // Do a operation similar to split_map_join for the
155
-            // regex matches, quoting each identifier
156
-            RE.split(s)
157
-                .into_iter()
158
-                .map(|p| self.driver.quote_identifier(p))
159
-                .collect::<Vec<String>>()
160
-                .join(" as ")
161
-        });
173
+        let fields = self.quote_fields(fields);
162 174
 
163 175
         self.state.append_select_string(&fields);
164 176
 
@@ -168,7 +180,8 @@ impl QueryBuilder {
168 180
     /// Set the fields to select from the database as a Vector
169 181
     ///
170 182
     /// ```no_run
171
-    /// # let mut qb = stringqb::query_builder::QueryBuilder::default();
183
+    /// # use stringqb::prelude::*;
184
+    /// # let mut qb = QueryBuilder::default();
172 185
     /// // You can also alias via a vector of fields
173 186
     /// qb.select_vec(vec!["foo as bar", "baz"]);
174 187
     /// ```
@@ -195,8 +208,9 @@ impl QueryBuilder {
195 208
     /// Specify the database table to select from
196 209
     ///
197 210
     /// ```no_run
198
-    /// # let mut qb = stringqb::query_builder::QueryBuilder::default();
199
-    /// // You can specifiy an alias for the table
211
+    /// # use stringqb::prelude::*;
212
+    /// # let mut qb = QueryBuilder::default();
213
+    /// // You can specify an alias for the table
200 214
     /// qb.from("products p");
201 215
     /// ```
202 216
     pub fn from(&mut self, table_name: &str) -> &mut Self {
@@ -215,7 +229,7 @@ impl QueryBuilder {
215 229
     ///
216 230
     /// ```no_run
217 231
     /// # use stringqb::prelude::*;
218
-    /// # let mut qb = stringqb::query_builder::QueryBuilder::default();
232
+    /// # let mut qb = QueryBuilder::default();
219 233
     /// // Search for a value that ends with "foo"
220 234
     /// qb.like("field", String::from("foo"), LikeWildcard::Before);
221 235
     ///
@@ -233,7 +247,7 @@ impl QueryBuilder {
233 247
     ///
234 248
     /// ```no_run
235 249
     /// # use stringqb::prelude::*;
236
-    /// # let mut qb = stringqb::query_builder::QueryBuilder::default();
250
+    /// # let mut qb = QueryBuilder::default();
237 251
     /// // Search for a value that ends with "foo"
238 252
     /// qb.or_like("field", String::from("foo"), LikeWildcard::Before);
239 253
     ///
@@ -251,7 +265,7 @@ impl QueryBuilder {
251 265
     ///
252 266
     /// ```no_run
253 267
     /// # use stringqb::prelude::*;
254
-    /// # let mut qb = stringqb::query_builder::QueryBuilder::default();
268
+    /// # let mut qb = QueryBuilder::default();
255 269
     /// // Search for a value that does not end with "foo"
256 270
     /// qb.not_like("field", String::from("foo"), LikeWildcard::Before);
257 271
     ///
@@ -269,7 +283,7 @@ impl QueryBuilder {
269 283
     ///
270 284
     /// ```no_run
271 285
     /// # use stringqb::prelude::*;
272
-    /// # let mut qb = stringqb::query_builder::QueryBuilder::default();
286
+    /// # let mut qb = QueryBuilder::default();
273 287
     /// // Search for a value that does not end with "foo"
274 288
     /// qb.or_not_like("field", String::from("foo"), LikeWildcard::Before);
275 289
     ///
@@ -393,16 +407,37 @@ impl QueryBuilder {
393 407
     }
394 408
 
395 409
     /// Specify a `where in` clause for the query, prefixed with `or`
410
+    ///
411
+    /// ```no_run
412
+    /// # use stringqb::prelude::*;
413
+    /// # let mut qb = QueryBuilder::default();
414
+    /// // Look for a set of rows matching the values passed
415
+    /// qb.or_where_in("key", vec![1,2,3]);
416
+    /// ```
396 417
     pub fn or_where_in(&mut self, key: &str, values: Vec<impl Any>) -> &mut Self {
397 418
         self._where_in(key, values, "IN", "OR")
398 419
     }
399 420
 
400 421
     /// Specify a `where not in` clause for the query
422
+    ///
423
+    /// ```no_run
424
+    /// # use stringqb::prelude::*;
425
+    /// # let mut qb = QueryBuilder::default();
426
+    /// // Look for a set of rows not matching the values passed
427
+    /// qb.where_not_in("key", vec![1,2,3]);
428
+    /// ```
401 429
     pub fn where_not_in(&mut self, key: &str, values: Vec<impl Any>) -> &mut Self {
402 430
         self._where_in(key, values, "NOT IN", "AND")
403 431
     }
404 432
 
405 433
     /// Specify a `where not in` clause for the query, prefixed with `or`
434
+    ///
435
+    /// ```no_run
436
+    /// # use stringqb::prelude::*;
437
+    /// # let mut qb = QueryBuilder::default();
438
+    /// // Look for a set of rows not matching the values passed
439
+    /// qb.or_where_not_in("key", vec![1,2,3]);
440
+    /// ```
406 441
     pub fn or_where_not_in(&mut self, key: &str, values: Vec<impl Any>) -> &mut Self {
407 442
         self._where_in(key, values, "NOT IN", "OR")
408 443
     }
@@ -412,6 +447,15 @@ impl QueryBuilder {
412 447
     // --------------------------------------------------------------------------
413 448
 
414 449
     /// Set a key and value for an insert or update query
450
+    ///
451
+    /// ```no_run
452
+    /// # use stringqb::prelude::*;
453
+    /// # let mut qb = QueryBuilder::default();
454
+    /// // Can be called multiple times to set multiple values
455
+    /// qb.set("foo", 3)
456
+    ///     .set("bar", 4)
457
+    ///     .insert("table");
458
+    /// ```
415 459
     pub fn set(&mut self, key: &str, value: impl Any) -> &mut Self {
416 460
         let key = self.driver.quote_identifier(key);
417 461
         self.state
@@ -431,11 +475,25 @@ impl QueryBuilder {
431 475
     }
432 476
 
433 477
     /// Convenience method for a `left` join
478
+    ///
479
+    /// ```no_run
480
+    /// # use stringqb::prelude::*;
481
+    /// # let mut qb = QueryBuilder::default();
482
+    /// // Note that the value is not prepared/escaped, due to it often being a column
483
+    /// qb.left_join("table1", "column1", "<>", "foo");
484
+    /// ```
434 485
     pub fn left_join(&mut self, table: &str, col: &str, op: &str, value: &str) -> &mut Self {
435 486
         self.join(table, col, op, value, JoinType::Left)
436 487
     }
437 488
 
438 489
     /// Convenience method for an `inner` join
490
+    ///
491
+    /// ```no_run
492
+    /// # use stringqb::prelude::*;
493
+    /// # let mut qb = QueryBuilder::default();
494
+    /// // Note that the value is not prepared/escaped, due to it often being a column
495
+    /// qb.inner_join("table1", "column1", "<>", "foo");
496
+    /// ```
439 497
     pub fn inner_join(&mut self, table: &str, col: &str, op: &str, value: &str) -> &mut Self {
440 498
         self.join(table, col, op, value, JoinType::Inner)
441 499
     }
@@ -445,7 +503,7 @@ impl QueryBuilder {
445 503
     /// ```no_run
446 504
     /// # use stringqb::prelude::*;
447 505
     /// # let mut qb = QueryBuilder::default();
448
-    /// // Note that the value is not escaped, due to it often being a column
506
+    /// // Note that the value is not prepared/escaped, due to it often being a column
449 507
     /// qb.join("table1", "column1", "<>", "foo", JoinType::Inner);
450 508
     /// ```
451 509
     pub fn join(
@@ -456,9 +514,16 @@ impl QueryBuilder {
456 514
         value: &str,
457 515
         join_type: JoinType,
458 516
     ) -> &mut Self {
459
-        let table = self.driver.quote_identifier(table);
460
-        let col = self.driver.quote_identifier(col);
461
-        let condition = table + " ON " + &col + op + value;
517
+        let col = self.quote_fields(col);
518
+        let table = self.quote_table(table);
519
+
520
+        let condition = format!(
521
+            "{} ON {}{}{}",
522
+            table,
523
+            &col,
524
+            op,
525
+            value
526
+        );
462 527
 
463 528
         let join_type = match join_type {
464 529
             JoinType::Cross => "CROSS ",
@@ -520,6 +585,11 @@ impl QueryBuilder {
520 585
 
521 586
     ///  Add an offset to the query
522 587
     pub fn offset(&mut self, offset: usize) -> &mut Self {
588
+        assert!(
589
+            self.state.offset.is_some(),
590
+            "You must set a limit to set an offset"
591
+        );
592
+
523 593
         self.state.offset = Some(offset);
524 594
 
525 595
         self
@@ -531,16 +601,28 @@ impl QueryBuilder {
531 601
 
532 602
     /// Start a logical grouping in the current query
533 603
     pub fn group_start(&mut self) -> &mut Self {
604
+        let conj = if ! self.state.has_where_clause() {
605
+            "\nWHERE "
606
+        } else {
607
+            " "
608
+        };
609
+
534 610
         self.state
535
-            .append_query_map(QueryClauseType::GroupStart, " ", "(");
611
+            .append_query_map(QueryClauseType::GroupStart, conj, "(");
536 612
 
537 613
         self
538 614
     }
539 615
 
540 616
     /// Start a logical grouping, prefixed with `not`
541 617
     pub fn not_group_start(&mut self) -> &mut Self {
618
+        let conj = if ! self.state.has_where_clause() {
619
+            "\nWHERE "
620
+        } else {
621
+            " AND "
622
+        };
623
+
542 624
         self.state
543
-            .append_query_map(QueryClauseType::GroupStart, " AND ", "NOT (");
625
+            .append_query_map(QueryClauseType::GroupStart, conj, "NOT (");
544 626
 
545 627
         self
546 628
     }
@@ -580,7 +662,7 @@ impl QueryBuilder {
580 662
     /// # let mut qb = QueryBuilder::default();
581 663
     /// // The get() method actually calls the driver to run
582 664
     /// // the SQL query
583
-    /// let query = db.select_vec(vec!["foo", "bar"])
665
+    /// let query = qb.select_vec(vec!["foo", "bar"])
584 666
     ///     .from("table t")
585 667
     ///     .get();
586 668
     /// ```
@@ -602,7 +684,7 @@ impl QueryBuilder {
602 684
     /// # let mut qb = QueryBuilder::default();
603 685
     /// // The insert() method actually calls the driver to run
604 686
     /// // the SQL query
605
-    /// let query = db.set("foo", 3)
687
+    /// let query = qb.set("foo", 3)
606 688
     ///     .insert("table");
607 689
     /// ```
608 690
     pub fn insert(&mut self, table: &str) {
@@ -618,7 +700,7 @@ impl QueryBuilder {
618 700
     /// # let mut qb = QueryBuilder::default();
619 701
     /// // The update() method actually calls the driver to run
620 702
     /// // the SQL query
621
-    /// let query = db.set("foo", 3)
703
+    /// let query = qb.set("foo", 3)
622 704
     ///     .wher("foo", 4)
623 705
     ///     .update("table");
624 706
     /// ```
@@ -629,6 +711,15 @@ impl QueryBuilder {
629 711
     }
630 712
 
631 713
     /// Execute the generated delete query
714
+    ///
715
+    /// ```no_run
716
+    /// # use stringqb::prelude::*;
717
+    /// # let mut qb = QueryBuilder::default();
718
+    /// // The delete() method actually calls the driver to run
719
+    /// // the SQL query
720
+    /// let query = qb.wher("foo", 3)
721
+    ///     .delete("table");
722
+    /// ```
632 723
     pub fn delete(&mut self, table: &str) {
633 724
         let sql = self.get_compiled_delete(table);
634 725
 
@@ -670,14 +761,14 @@ impl QueryBuilder {
670 761
     // --------------------------------------------------------------------------
671 762
 
672 763
     /// Get a new instance of the query builder
673
-    pub fn reset(&mut self) -> &Self {
764
+    pub fn reset(&mut self) -> &mut Self {
674 765
         self.state = QueryState::new();
675 766
 
676 767
         self
677 768
     }
678 769
 
679 770
     /// Execute an SQL query with no parameters
680
-    pub fn basic_query(&mut self, sql: &str) {
771
+    pub fn basic_query(&mut self, sql: &str) -> Result<Box<dyn Any>, Box<dyn Any>> {
681 772
         self.driver.query(sql)
682 773
     }
683 774
 
@@ -691,6 +782,32 @@ impl QueryBuilder {
691 782
         unimplemented!();
692 783
     }
693 784
 
785
+    /// Quotes table column(s)/field(s) accounting for 'as' aliases
786
+    fn quote_fields(&mut self, fields: &str) -> String {
787
+        lazy_static! {
788
+            static ref RE: Regex = Regex::new(r"(?i) as ").unwrap();
789
+        };
790
+
791
+        split_map_join(fields, ",", |s| {
792
+            if !RE.is_match(s) {
793
+                return self.driver.quote_identifier(s.trim());
794
+            }
795
+
796
+            // Do a operation similar to split_map_join for the
797
+            // regex matches, quoting each identifier
798
+            RE.split(s)
799
+                .into_iter()
800
+                .map(|p| self.driver.quote_identifier(p))
801
+                .collect::<Vec<String>>()
802
+                .join(" AS ")
803
+        })
804
+    }
805
+
806
+    /// Quotes table(s), accounting for aliases
807
+    pub fn quote_table(&mut self, table: &str) -> String {
808
+        split_map_join(table, " ", |s| self.driver.quote_identifier(s))
809
+    }
810
+
694 811
     // --------------------------------------------------------------------------
695 812
     // ! Implementation Details
696 813
     // --------------------------------------------------------------------------
@@ -703,6 +820,12 @@ impl QueryBuilder {
703 820
         like: &str,
704 821
         conj: &str,
705 822
     ) -> &mut Self {
823
+        let conj = if ! self.state.has_where_clause() {
824
+            "\nWHERE "
825
+        } else {
826
+            conj
827
+        };
828
+
706 829
         let field = self.driver.quote_identifier(field);
707 830
 
708 831
         let like = format!("{} {} ?", field, like);
@@ -775,6 +898,12 @@ impl QueryBuilder {
775 898
 
776 899
         let str = format!("{} {} ({}) ", key, in_str, placeholders.join(","));
777 900
 
901
+        let conj = if ! self.state.has_where_clause() {
902
+            "\nWHERE "
903
+        } else {
904
+            conj
905
+        };
906
+
778 907
         self.state
779 908
             .append_query_map(QueryClauseType::WhereIn, conj, &str);
780 909
 
@@ -805,21 +934,29 @@ impl QueryBuilder {
805 934
 
806 935
         item += &item2;
807 936
 
937
+        let conj = if self.state.query_map.len() == 0 || ( ! self.state.has_where_clause()) {
938
+            String::from("\nWHERE")
939
+        } else {
940
+            String::from(conj)
941
+        };
942
+
808 943
         let conj = if last_item.is_some() {
809 944
             let last_item = last_item.unwrap();
810 945
 
811 946
             match last_item.clause_type {
812 947
                 QueryClauseType::GroupStart => String::from(""),
813
-                _ => format!(" {} ", conj),
948
+                _ => format!("{} ", conj),
814 949
             }
815 950
         } else {
816
-            format!(" {} ", conj)
951
+            format!("{} ", conj)
817 952
         };
818 953
 
819 954
         self.state
820 955
             .append_query_map(QueryClauseType::Where, &conj, &item);
821 956
     }
822 957
 
958
+
959
+
823 960
     fn compile(&self, query_type: QueryType, table: &str) -> String {
824 961
         // Get the base clause for the query
825 962
         let base_sql = self.compile_type(query_type, &self.driver.quote_identifier(table));
@@ -893,7 +1030,7 @@ impl QueryBuilder {
893 1030
         // @TODO determine query result type
894 1031
         // @TODO prepare/execute query, and return result
895 1032
         let stmt = self.prepare(sql);
896
-        self.execute(&stmt, values)
1033
+        self.execute(&stmt, &values)
897 1034
     }
898 1035
 }
899 1036
 
@@ -1041,12 +1178,6 @@ impl QueryState {
1041 1178
     }
1042 1179
 
1043 1180
     fn append_query_map(&mut self, clause_type: QueryClauseType, conj: &str, s: &str) -> &mut Self {
1044
-        let conj = if self.query_map.len() == 0 {
1045
-            " WHERE "
1046
-        } else {
1047
-            conj
1048
-        };
1049
-
1050 1181
         self.query_map.push(QueryClause::new(clause_type, conj, s));
1051 1182
 
1052 1183
         self
@@ -1110,6 +1241,20 @@ impl QueryState {
1110 1241
         &mut self.where_values
1111 1242
     }
1112 1243
 
1244
+    fn has_where_clause(&self) -> bool {
1245
+        let has_clause = false;
1246
+
1247
+        for clause in self.query_map.iter() {
1248
+            match clause.clause_type {
1249
+                QueryClauseType::Where => return true,
1250
+                QueryClauseType::WhereIn => return true,
1251
+                _ => (),
1252
+            }
1253
+        }
1254
+
1255
+        has_clause
1256
+    }
1257
+
1113 1258
     fn set_from_string(&mut self, s: &str) -> &mut Self {
1114 1259
         self.from_string = String::from(s);
1115 1260
 
@@ -1172,7 +1317,7 @@ mod tests {
1172 1317
         qb.from("test").where_in("foo", vec![0, 1, 2, 3, 4, 5]);
1173 1318
 
1174 1319
         let sql = qb.get_compiled_select();
1175
-        let expected = "SELECT *\nFROM \"test\" WHERE \"foo\" IN (?,?,?,?,?,?) ";
1320
+        let expected = "SELECT *\nFROM \"test\"\nWHERE \"foo\" IN (?,?,?,?,?,?) ";
1176 1321
 
1177 1322
         assert_eq!(sql, expected);
1178 1323
     }

+ 3
- 6
src/types.rs View File

@@ -86,8 +86,8 @@ pub enum ToDriverOutput<'a> {
86 86
 // Generically allow any type that can be converted into a ValueRef
87 87
 // to be converted into a ToSqlOutput as well.
88 88
 impl<'a, T: ?Sized> From<&'a T> for ToDriverOutput<'a>
89
-    where
90
-        &'a T: Into<ValueRef<'a>>,
89
+where
90
+    &'a T: Into<ValueRef<'a>>,
91 91
 {
92 92
     fn from(t: &'a T) -> Self {
93 93
         ToDriverOutput::Borrowed(t.into())
@@ -120,16 +120,13 @@ impl<'a, T: ?Sized> From<&'a T> for ToDriverOutput<'a>
120 120
 //from_value!(f64);
121 121
 //from_value!(Vec<u8>);
122 122
 
123
-
124 123
 /// Types that can be converted to a type that the driver understands
125 124
 pub trait ToDriver {
126 125
     fn to_driver(&self) -> Result<ToDriverOutput<'_>, ()>;
127 126
 }
128 127
 
129 128
 /// A trait for types that can be created from the result of a query on the driver
130
-pub trait FromDriver: Sized {
131
-
132
-}
129
+pub trait FromDriver: Sized {}
133 130
 
134 131
 /// Enum struct for mapping between database and Rust types
135 132
 #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]

+ 3
- 3
tests/integration_test.rs View File

@@ -15,7 +15,7 @@ fn select_keys_as_query() {
15 15
 
16 16
     let sql = qb.select("foo as bar, baz").from("a").get_compiled_select();
17 17
 
18
-    assert_eq!(sql, "SELECT \"foo\" as \"bar\",\"baz\"\nFROM \"a\"");
18
+    assert_eq!(sql, "SELECT \"foo\" AS \"bar\",\"baz\"\nFROM \"a\"");
19 19
 }
20 20
 
21 21
 #[test]
@@ -54,7 +54,7 @@ fn select_where() {
54 54
     qb.from("test").r#where("foo", "bar");
55 55
 
56 56
     let sql = qb.get_compiled_select();
57
-    let expected = "SELECT *\nFROM \"test\" WHERE \"foo\"=?";
57
+    let expected = "SELECT *\nFROM \"test\"\nWHERE \"foo\"=?";
58 58
 
59 59
     assert_eq!(sql, expected);
60 60
 }
@@ -66,7 +66,7 @@ fn select_where_in() {
66 66
     qb.from("test").where_in("foo", vec![0, 1, 2, 3, 4, 5]);
67 67
 
68 68
     let sql = qb.get_compiled_select();
69
-    let expected = "SELECT *\nFROM \"test\" WHERE \"foo\" IN (?,?,?,?,?,?) ";
69
+    let expected = "SELECT *\nFROM \"test\"\nWHERE \"foo\" IN (?,?,?,?,?,?) ";
70 70
 
71 71
     assert_eq!(sql, expected);
72 72
 }

Loading…
Cancel
Save