1 use diesel::*;
2 use helpers::*;
3 
4 table! {
5     users {
6         id -> Integer,
7         name -> VarChar,
8         hair_color -> Nullable<VarChar>,
9     }
10 }
11 
12 #[test]
simple_struct_definition()13 fn simple_struct_definition() {
14     #[derive(Insertable)]
15     #[table_name = "users"]
16     struct NewUser {
17         name: String,
18         hair_color: String,
19     }
20 
21     let conn = connection();
22     let new_user = NewUser {
23         name: "Sean".into(),
24         hair_color: "Black".into(),
25     };
26     insert_into(users::table)
27         .values(new_user)
28         .execute(&conn)
29         .unwrap();
30 
31     let saved = users::table
32         .select((users::name, users::hair_color))
33         .load::<(String, Option<String>)>(&conn);
34     let expected = vec![("Sean".to_string(), Some("Black".to_string()))];
35     assert_eq!(Ok(expected), saved);
36 }
37 
38 #[test]
simple_reference_definition()39 fn simple_reference_definition() {
40     #[derive(Insertable)]
41     #[table_name = "users"]
42     struct NewUser {
43         name: String,
44         hair_color: String,
45     }
46 
47     let conn = connection();
48     let new_user = NewUser {
49         name: "Sean".into(),
50         hair_color: "Black".into(),
51     };
52     insert_into(users::table)
53         .values(&new_user)
54         .execute(&conn)
55         .unwrap();
56 
57     let saved = users::table
58         .select((users::name, users::hair_color))
59         .load::<(String, Option<String>)>(&conn);
60     let expected = vec![("Sean".to_string(), Some("Black".to_string()))];
61     assert_eq!(Ok(expected), saved);
62 }
63 
64 macro_rules! test_struct_definition {
65     ($test_name:ident, $struct_def:item) => {
66         #[test]
67         fn $test_name() {
68             #[derive(Insertable)]
69             #[table_name = "users"]
70             $struct_def
71 
72             let conn = connection();
73             let new_user = NewUser { name: "Sean".into(), hair_color: None };
74             insert_into(users::table).values(&new_user).execute(&conn).unwrap();
75 
76             let saved = users::table.select((users::name, users::hair_color))
77                 .load::<(String, Option<String>)>(&conn);
78             let expected = vec![("Sean".to_string(), Some("Green".to_string()))];
79             assert_eq!(Ok(expected), saved);
80         }
81     }
82 }
83 
84 test_struct_definition! {
85     struct_with_option_field,
86     struct NewUser {
87         name: String,
88         hair_color: Option<String>,
89     }
90 }
91 
92 test_struct_definition! {
93     pub_struct_definition,
94     pub struct NewUser {
95         name: String,
96         hair_color: Option<String>,
97     }
98 }
99 
100 test_struct_definition! {
101     struct_with_pub_field,
102     pub struct NewUser {
103         pub name: String,
104         hair_color: Option<String>,
105     }
106 }
107 
108 test_struct_definition! {
109     struct_with_pub_option_field,
110     pub struct NewUser {
111         name: String,
112         pub hair_color: Option<String>,
113     }
114 }
115 
116 test_struct_definition! {
117     named_struct_with_borrowed_body,
118     struct NewUser<'a> {
119         name: &'a str,
120         hair_color: Option<&'a str>,
121     }
122 }
123 
124 #[test]
named_struct_with_renamed_field()125 fn named_struct_with_renamed_field() {
126     #[derive(Insertable)]
127     #[table_name = "users"]
128     struct NewUser {
129         #[column_name = "name"]
130         my_name: String,
131         hair_color: String,
132     }
133 
134     let conn = connection();
135     let new_user = NewUser {
136         my_name: "Sean".into(),
137         hair_color: "Black".into(),
138     };
139     insert_into(users::table)
140         .values(&new_user)
141         .execute(&conn)
142         .unwrap();
143 
144     let saved = users::table
145         .select((users::name, users::hair_color))
146         .load::<(String, Option<String>)>(&conn);
147     let expected = vec![("Sean".to_string(), Some("Black".to_string()))];
148     assert_eq!(Ok(expected), saved);
149 }
150 
151 #[test]
named_struct_with_renamed_option_field()152 fn named_struct_with_renamed_option_field() {
153     #[derive(Insertable)]
154     #[table_name = "users"]
155     struct NewUser {
156         #[column_name = "name"]
157         my_name: String,
158         #[column_name = "hair_color"]
159         my_hair_color: Option<String>,
160     }
161 
162     let conn = connection();
163     let new_user = NewUser {
164         my_name: "Sean".into(),
165         my_hair_color: None,
166     };
167     insert_into(users::table)
168         .values(&new_user)
169         .execute(&conn)
170         .unwrap();
171 
172     let saved = users::table
173         .select((users::name, users::hair_color))
174         .load::<(String, Option<String>)>(&conn);
175     let expected = vec![("Sean".to_string(), Some("Green".to_string()))];
176     assert_eq!(Ok(expected), saved);
177 }
178 
179 #[test]
tuple_struct()180 fn tuple_struct() {
181     #[derive(Insertable)]
182     #[table_name = "users"]
183     struct NewUser<'a>(
184         #[column_name = "name"] &'a str,
185         #[column_name = "hair_color"] Option<&'a str>,
186     );
187 
188     let conn = connection();
189     let new_user = NewUser("Sean", None);
190     insert_into(users::table)
191         .values(&new_user)
192         .execute(&conn)
193         .unwrap();
194 
195     let saved = users::table
196         .select((users::name, users::hair_color))
197         .load::<(String, Option<String>)>(&conn);
198     let expected = vec![("Sean".to_string(), Some("Green".to_string()))];
199     assert_eq!(Ok(expected), saved);
200 }
201 
202 #[test]
named_struct_with_unusual_reference_type()203 fn named_struct_with_unusual_reference_type() {
204     #[derive(Insertable)]
205     #[table_name = "users"]
206     struct NewUser<'a> {
207         name: &'a String,
208         hair_color: Option<&'a String>,
209     }
210 
211     let conn = connection();
212     let sean = "Sean".to_string();
213     let black = "Black".to_string();
214     let new_user = NewUser {
215         name: &sean,
216         hair_color: Some(&black),
217     };
218     insert_into(users::table)
219         .values(&new_user)
220         .execute(&conn)
221         .unwrap();
222 
223     let saved = users::table
224         .select((users::name, users::hair_color))
225         .load(&conn);
226     let expected = vec![(sean.clone(), Some(black.clone()))];
227     assert_eq!(Ok(expected), saved);
228 }
229 
230 #[test]
231 #[cfg(all(feature = "postgres", not(feature = "sqlite")))]
insertable_with_slice_of_borrowed()232 fn insertable_with_slice_of_borrowed() {
233     table! {
234         posts {
235             id -> Serial,
236             tags -> Array<Text>,
237         }
238     }
239 
240     #[derive(Insertable)]
241     #[table_name = "posts"]
242     struct NewPost<'a> {
243         tags: &'a [&'a str],
244     }
245 
246     let conn = connection();
247     sql_query("DROP TABLE IF EXISTS posts CASCADE")
248         .execute(&conn)
249         .unwrap();
250     sql_query("CREATE TABLE posts (id SERIAL PRIMARY KEY, tags TEXT[] NOT NULL)")
251         .execute(&conn)
252         .unwrap();
253     let new_post = NewPost {
254         tags: &["hi", "there"],
255     };
256     insert_into(posts::table)
257         .values(&new_post)
258         .execute(&conn)
259         .unwrap();
260 
261     let saved = posts::table.select(posts::tags).load::<Vec<String>>(&conn);
262     let expected = vec![vec![String::from("hi"), String::from("there")]];
263     assert_eq!(Ok(expected), saved);
264 }
265 
266 #[test]
embedded_struct()267 fn embedded_struct() {
268     #[derive(Insertable)]
269     #[table_name = "users"]
270     struct NameAndHairColor<'a> {
271         name: &'a str,
272         hair_color: &'a str,
273     }
274 
275     #[derive(Insertable)]
276     struct User<'a> {
277         id: i32,
278         #[diesel(embed)]
279         name_and_hair_color: NameAndHairColor<'a>,
280     }
281 
282     let conn = connection();
283     let new_user = User {
284         id: 1,
285         name_and_hair_color: NameAndHairColor {
286             name: "Sean",
287             hair_color: "Black",
288         },
289     };
290     insert_into(users::table)
291         .values(&new_user)
292         .execute(&conn)
293         .unwrap();
294 
295     let saved = users::table.load::<(i32, String, Option<String>)>(&conn);
296     let expected = vec![(1, "Sean".to_string(), Some("Black".to_string()))];
297     assert_eq!(Ok(expected), saved);
298 }
299