1
//! Integration tests for the CRUD operations available in `Canyon` that
2
//! generates and executes *INSERT* statements
3
use canyon_sql::crud::CrudOperations;
4

            
5
#[cfg(feature = "mysql")]
6
use crate::constants::MYSQL_DS;
7
#[cfg(feature = "mssql")]
8
use crate::constants::SQL_SERVER_DS;
9

            
10
use crate::tests_models::league::*;
11

            
12
/// Inserts a new record on the database, given an entity that is
13
/// annotated with `#[canyon_entity]` macro over a *T* type.
14
///
15
/// For insert a new record on a database, the *insert* operation needs
16
/// some special requirements:
17
/// > - We need a mutable instance of `T`. If the operation completes
18
/// successfully, the insert operation will automatically set the autogenerated
19
/// value for the `primary_key` annotated field in it.
20
///
21
/// > - It's considered a good practice to initialize that concrete field with
22
/// the `Default` trait, because the value on the primary key field will be
23
/// ignored at the execution time of the insert, and updated with the autogenerated
24
/// value by the database.
25
///
26
/// By default, the `#[primary_key]` annotation means autogenerated and autoincremental.
27
/// You can configure not autoincremental via macro annotation parameters (please,
28
/// refer to the docs [here]() for more info.)
29
///
30
/// If the type hasn't a `#[primary_key]` annotation, or the annotation contains
31
/// an argument specifying not autoincremental behaviour, all the fields will be
32
/// inserted on the database and no returning value will be placed in any field.
33
#[cfg(feature = "postgres")]
34
20
#[canyon_sql::macros::canyon_tokio_test]
35
1
fn test_crud_insert_operation() {
36
1
    let mut new_league: League = League {
37
1
        id: Default::default(),
38
        ext_id: 7892635306594_i64,
39
1
        slug: "some-new-league".to_string(),
40
1
        name: "Some New League".to_string(),
41
1
        region: "Bahía de cochinos".to_string(),
42
1
        image_url: "https://nobodyspectsandimage.io".to_string(),
43
    };
44

            
45
    // We insert the instance on the database, on the `League` entity
46
3
    new_league.insert().await.expect("Failed insert operation");
47

            
48
    // Now, in the `id` field of the instance, we have the autogenerated
49
    // value for the primary key field, which is id. So, we can query the
50
    // database again with the find by primary key operation to check if
51
    // the value was really inserted
52
4
    let inserted_league = League::find_by_pk(&new_league.id)
53
4
        .await
54
        .expect("Failed the query to the database")
55
        .expect("No entity found for the primary key value passed in");
56

            
57
1
    assert_eq!(new_league.id, inserted_league.id);
58
}
59

            
60
/// Same as the insert operation above, but targeting the database defined in
61
/// the specified datasource
62
#[cfg(feature = "mssql")]
63
18
#[canyon_sql::macros::canyon_tokio_test]
64
1
fn test_crud_insert_datasource_mssql_operation() {
65
1
    let mut new_league: League = League {
66
1
        id: Default::default(),
67
        ext_id: 7892635306594_i64,
68
1
        slug: "some-new-league".to_string(),
69
1
        name: "Some New League".to_string(),
70
1
        region: "Bahía de cochinos".to_string(),
71
1
        image_url: "https://nobodyspectsandimage.io".to_string(),
72
    };
73

            
74
    // We insert the instance on the database, on the `League` entity
75
4
    new_league
76
        .insert_datasource(SQL_SERVER_DS)
77
3
        .await
78
        .expect("Failed insert datasource operation");
79

            
80
    // Now, in the `id` field of the instance, we have the autogenerated
81
    // value for the primary key field, which is id. So, we can query the
82
    // database again with the find by primary key operation to check if
83
    // the value was really inserted
84
4
    let inserted_league = League::find_by_pk_datasource(&new_league.id, SQL_SERVER_DS)
85
3
        .await
86
        .expect("Failed the query to the database")
87
        .expect("No entity found for the primary key value passed in");
88

            
89
1
    assert_eq!(new_league.id, inserted_league.id);
90
}
91

            
92
/// Same as the insert operation above, but targeting the database defined in
93
/// the specified datasource
94
#[cfg(feature = "mysql")]
95
30
#[canyon_sql::macros::canyon_tokio_test]
96
1
fn test_crud_insert_datasource_mysql_operation() {
97
1
    let mut new_league: League = League {
98
1
        id: Default::default(),
99
        ext_id: 7892635306594_i64,
100
1
        slug: "some-new-league".to_string(),
101
1
        name: "Some New League".to_string(),
102
1
        region: "Bahía de cochinos".to_string(),
103
1
        image_url: "https://nobodyspectsandimage.io".to_string(),
104
    };
105

            
106
    // We insert the instance on the database, on the `League` entity
107
4
    new_league
108
        .insert_datasource(MYSQL_DS)
109
9
        .await
110
        .expect("Failed insert datasource operation");
111

            
112
    // Now, in the `id` field of the instance, we have the autogenerated
113
    // value for the primary key field, which is id. So, we can query the
114
    // database again with the find by primary key operation to check if
115
    // the value was really inserted
116
4
    let inserted_league = League::find_by_pk_datasource(&new_league.id, MYSQL_DS)
117
9
        .await
118
        .expect("Failed the query to the database")
119
        .expect("No entity found for the primary key value passed in");
120

            
121
1
    assert_eq!(new_league.id, inserted_league.id);
122
}
123

            
124
/// The multi insert operation is a shorthand for insert multiple instances of *T*
125
/// in the database at once.
126
///
127
/// It works pretty much the same that the insert operation, with the same behaviour
128
/// of the `#[primary_key]` annotation over some field. It will auto set the primary
129
/// key field with the autogenerated value on the database on the insert operation, but
130
/// for every entity passed in as an array of mutable instances of `T`.
131
///
132
/// The instances without `#[primary_key]` inserts all the values on the instaqce fields
133
/// on the database.
134
#[cfg(feature = "postgres")]
135
28
#[canyon_sql::macros::canyon_tokio_test]
136
1
fn test_crud_multi_insert_operation() {
137
1
    let mut new_league_mi: League = League {
138
1
        id: Default::default(),
139
        ext_id: 54376478_i64,
140
1
        slug: "some-new-random-league".to_string(),
141
1
        name: "Some New Random League".to_string(),
142
1
        region: "Unknown".to_string(),
143
1
        image_url: "https://what-a-league.io".to_string(),
144
    };
145
1
    let mut new_league_mi_2: League = League {
146
1
        id: Default::default(),
147
        ext_id: 3475689769678906_i64,
148
1
        slug: "new-league-2".to_string(),
149
1
        name: "New League 2".to_string(),
150
1
        region: "Really unknown".to_string(),
151
1
        image_url: "https://what-an-unknown-league.io".to_string(),
152
    };
153
1
    let mut new_league_mi_3: League = League {
154
1
        id: Default::default(),
155
        ext_id: 46756867_i64,
156
1
        slug: "a-new-multinsert".to_string(),
157
1
        name: "New League 3".to_string(),
158
1
        region: "The dark side of the moon".to_string(),
159
1
        image_url: "https://interplanetary-league.io".to_string(),
160
    };
161

            
162
    // Insert the instance as database entities
163
4
    new_league_mi
164
        .insert()
165
4
        .await
166
        .expect("Failed insert datasource operation");
167
4
    new_league_mi_2
168
        .insert()
169
4
        .await
170
        .expect("Failed insert datasource operation");
171
4
    new_league_mi_3
172
        .insert()
173
4
        .await
174
        .expect("Failed insert datasource operation");
175

            
176
    // Recover the inserted data by primary key
177
4
    let inserted_league = League::find_by_pk(&new_league_mi.id)
178
4
        .await
179
        .expect("[1] - Failed the query to the database")
180
        .expect("[1] - No entity found for the primary key value passed in");
181
4
    let inserted_league_2 = League::find_by_pk(&new_league_mi_2.id)
182
4
        .await
183
        .expect("[2] - Failed the query to the database")
184
        .expect("[2] - No entity found for the primary key value passed in");
185
4
    let inserted_league_3 = League::find_by_pk(&new_league_mi_3.id)
186
4
        .await
187
        .expect("[3] - Failed the query to the database")
188
        .expect("[3] - No entity found for the primary key value passed in");
189

            
190
1
    assert_eq!(new_league_mi.id, inserted_league.id);
191
1
    assert_eq!(new_league_mi_2.id, inserted_league_2.id);
192
1
    assert_eq!(new_league_mi_3.id, inserted_league_3.id);
193
}
194

            
195
/// Same as the multi insert above, but with the specified datasource
196
#[cfg(feature = "mssql")]
197
23
#[canyon_sql::macros::canyon_tokio_test]
198
1
fn test_crud_multi_insert_datasource_mssql_operation() {
199
1
    let mut new_league_mi: League = League {
200
1
        id: Default::default(),
201
        ext_id: 54376478_i64,
202
1
        slug: "some-new-random-league".to_string(),
203
1
        name: "Some New Random League".to_string(),
204
1
        region: "Unknown".to_string(),
205
1
        image_url: "https://what-a-league.io".to_string(),
206
    };
207
1
    let mut new_league_mi_2: League = League {
208
1
        id: Default::default(),
209
        ext_id: 3475689769678906_i64,
210
1
        slug: "new-league-2".to_string(),
211
1
        name: "New League 2".to_string(),
212
1
        region: "Really unknown".to_string(),
213
1
        image_url: "https://what-an-unknown-league.io".to_string(),
214
    };
215
1
    let mut new_league_mi_3: League = League {
216
1
        id: Default::default(),
217
        ext_id: 46756867_i64,
218
1
        slug: "a-new-multinsert".to_string(),
219
1
        name: "New League 3".to_string(),
220
1
        region: "The dark side of the moon".to_string(),
221
1
        image_url: "https://interplanetary-league.io".to_string(),
222
    };
223

            
224
    // Insert the instance as database entities
225
4
    new_league_mi
226
        .insert_datasource(SQL_SERVER_DS)
227
3
        .await
228
        .expect("Failed insert datasource operation");
229
4
    new_league_mi_2
230
        .insert_datasource(SQL_SERVER_DS)
231
3
        .await
232
        .expect("Failed insert datasource operation");
233
4
    new_league_mi_3
234
        .insert_datasource(SQL_SERVER_DS)
235
3
        .await
236
        .expect("Failed insert datasource operation");
237

            
238
    // Recover the inserted data by primary key
239
4
    let inserted_league = League::find_by_pk_datasource(&new_league_mi.id, SQL_SERVER_DS)
240
3
        .await
241
        .expect("[1] - Failed the query to the database")
242
        .expect("[1] - No entity found for the primary key value passed in");
243
4
    let inserted_league_2 = League::find_by_pk_datasource(&new_league_mi_2.id, SQL_SERVER_DS)
244
3
        .await
245
        .expect("[2] - Failed the query to the database")
246
        .expect("[2] - No entity found for the primary key value passed in");
247
4
    let inserted_league_3 = League::find_by_pk_datasource(&new_league_mi_3.id, SQL_SERVER_DS)
248
3
        .await
249
        .expect("[3] - Failed the query to the database")
250
        .expect("[3] - No entity found for the primary key value passed in");
251

            
252
1
    assert_eq!(new_league_mi.id, inserted_league.id);
253
1
    assert_eq!(new_league_mi_2.id, inserted_league_2.id);
254
1
    assert_eq!(new_league_mi_3.id, inserted_league_3.id);
255
}
256

            
257
/// Same as the multi insert above, but with the specified datasource
258
#[cfg(feature = "mysql")]
259
39
#[canyon_sql::macros::canyon_tokio_test]
260
1
fn test_crud_multi_insert_datasource_mysql_operation() {
261
1
    let mut new_league_mi: League = League {
262
1
        id: Default::default(),
263
        ext_id: 54376478_i64,
264
1
        slug: "some-new-random-league".to_string(),
265
1
        name: "Some New Random League".to_string(),
266
1
        region: "Unknown".to_string(),
267
1
        image_url: "https://what-a-league.io".to_string(),
268
    };
269
1
    let mut new_league_mi_2: League = League {
270
1
        id: Default::default(),
271
        ext_id: 3475689769678906_i64,
272
1
        slug: "new-league-2".to_string(),
273
1
        name: "New League 2".to_string(),
274
1
        region: "Really unknown".to_string(),
275
1
        image_url: "https://what-an-unknown-league.io".to_string(),
276
    };
277
1
    let mut new_league_mi_3: League = League {
278
1
        id: Default::default(),
279
        ext_id: 46756867_i64,
280
1
        slug: "a-new-multinsert".to_string(),
281
1
        name: "New League 3".to_string(),
282
1
        region: "The dark side of the moon".to_string(),
283
1
        image_url: "https://interplanetary-league.io".to_string(),
284
    };
285

            
286
    // Insert the instance as database entities
287
4
    new_league_mi
288
        .insert_datasource(MYSQL_DS)
289
9
        .await
290
        .expect("Failed insert datasource operation");
291
4
    new_league_mi_2
292
        .insert_datasource(MYSQL_DS)
293
9
        .await
294
        .expect("Failed insert datasource operation");
295
4
    new_league_mi_3
296
        .insert_datasource(MYSQL_DS)
297
4
        .await
298
        .expect("Failed insert datasource operation");
299

            
300
    // Recover the inserted data by primary key
301
4
    let inserted_league = League::find_by_pk_datasource(&new_league_mi.id, MYSQL_DS)
302
4
        .await
303
        .expect("[1] - Failed the query to the database")
304
        .expect("[1] - No entity found for the primary key value passed in");
305
4
    let inserted_league_2 = League::find_by_pk_datasource(&new_league_mi_2.id, MYSQL_DS)
306
4
        .await
307
        .expect("[2] - Failed the query to the database")
308
        .expect("[2] - No entity found for the primary key value passed in");
309
4
    let inserted_league_3 = League::find_by_pk_datasource(&new_league_mi_3.id, MYSQL_DS)
310
4
        .await
311
        .expect("[3] - Failed the query to the database")
312
        .expect("[3] - No entity found for the primary key value passed in");
313

            
314
1
    assert_eq!(new_league_mi.id, inserted_league.id);
315
1
    assert_eq!(new_league_mi_2.id, inserted_league_2.id);
316
1
    assert_eq!(new_league_mi_3.id, inserted_league_3.id);
317
}