1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
use crate::db_object::{DBObject, OrderTypes};
use crate::df_world::DBDFWorld;
use crate::schema::historical_event_collections;
use crate::DbConnection;
use df_st_core::fillable::{Fillable, Filler};
use df_st_core::item_count::ItemCount;
use df_st_derive::{Fillable, HashAndPartialEqById};
use diesel::expression_methods::ExpressionMethods;
use diesel::prelude::*;
use diesel::query_dsl::RunQueryDsl;
use diesel::Queryable;
use failure::Error;
use std::collections::HashMap;

mod hec_a_support_merc_hf_id;
mod hec_attacking_hf_id;
mod hec_d_support_merc_hf_id;
mod hec_defending_hf_id;
mod hec_he_id;
mod hec_individual_merc;
mod hec_noncom_hf_id;
mod hec_outcome;
mod hec_related_id;
mod historical_event_collection_a_c;
mod historical_event_collection_d_z;
pub use hec_a_support_merc_hf_id::HECASupportMercHFID;
pub use hec_attacking_hf_id::HECAttackingHFID;
pub use hec_d_support_merc_hf_id::HECDSupportMercHFID;
pub use hec_defending_hf_id::HECDefendingHFID;
pub use hec_he_id::HECHEID;
pub use hec_individual_merc::HECIndividualMerc;
pub use hec_noncom_hf_id::HECNoncomHFID;
pub use hec_outcome::HECOutcome;
pub use hec_related_id::HECRelatedID;
pub use historical_event_collection_a_c::HistoricalEventCollectionAC;
pub use historical_event_collection_d_z::HistoricalEventCollectionDZ;

#[derive(
    Clone,
    Debug,
    AsChangeset,
    Identifiable,
    HashAndPartialEqById,
    Queryable,
    Insertable,
    Fillable,
    Default,
)]
#[table_name = "historical_event_collections"]
pub struct HistoricalEventCollection {
    pub id: i32,
    pub world_id: i32,
    pub type_: Option<String>,
    pub start_year: Option<i32>,
    pub start_seconds72: Option<i32>,
    pub end_year: Option<i32>,
    pub end_seconds72: Option<i32>,
}

impl HistoricalEventCollection {
    pub fn new() -> Self {
        Self::default()
    }
}

impl DBObject<df_st_core::HistoricalEventCollection, HistoricalEventCollection>
    for HistoricalEventCollection
{
    fn add_missing_data_advanced(core_world: &df_st_core::DFWorld, world: &mut DBDFWorld) {
        for hec in core_world.historical_event_collections.values() {
            // Add he_ids list
            for item in &hec.he_ids {
                let mut db_item = HECHEID::new();
                db_item.hec_id = hec.id;
                db_item.he_id = *item;
                world.hec_he_ids.push(db_item);
            }
            // Add hec_ids list
            for item in &hec.hec_ids {
                let mut db_item = HECRelatedID::new();
                db_item.hec_id = hec.id;
                db_item.rel_hec_id = *item;
                world.hec_related_ids.push(db_item);
            }
            // Add individual_merc list
            for item in &hec.individual_merc {
                let mut db_item = HECIndividualMerc::new();
                db_item.hec_id = hec.id;
                db_item.individual_merc = *item;
                world.hec_individual_mercs.push(db_item);
            }
            // Add noncom_hf_id list
            for item in &hec.noncom_hf_id {
                let mut db_item = HECNoncomHFID::new();
                db_item.hec_id = hec.id;
                db_item.noncom_hf_id = *item;
                world.hec_noncom_hf_ids.push(db_item);
            }
            // Add outcome list
            for item in &hec.outcome {
                let mut db_item = HECOutcome::new();
                db_item.hec_id = hec.id;
                db_item.outcome = item.clone();
                world.hec_outcomes.push(db_item);
            }
            // Add attacking_hf_id list
            for item in &hec.attacking_hf_id {
                let mut db_item = HECAttackingHFID::new();
                db_item.hec_id = hec.id;
                db_item.attacking_hf_id = *item;
                world.hec_attacking_hf_ids.push(db_item);
            }
            // Add defending_hf_id list
            for item in &hec.defending_hf_id {
                let mut db_item = HECDefendingHFID::new();
                db_item.hec_id = hec.id;
                db_item.defending_hf_id = *item;
                world.hec_defending_hf_ids.push(db_item);
            }
            // Add a_support_merc_hf_id list
            for item in &hec.a_support_merc_hf_id {
                let mut db_item = HECASupportMercHFID::new();
                db_item.hec_id = hec.id;
                db_item.a_support_merc_hf_id = *item;
                world.hec_a_support_merc_hf_ids.push(db_item);
            }
            // Add d_support_merc_hf_id list
            for item in &hec.d_support_merc_hf_id {
                let mut db_item = HECDSupportMercHFID::new();
                db_item.hec_id = hec.id;
                db_item.d_support_merc_hf_id = *item;
                world.hec_d_support_merc_hf_ids.push(db_item);
            }
        }
    }

    #[cfg(feature = "postgres")]
    fn insert_into_db(
        conn: &DbConnection,
        historical_event_collections: &[HistoricalEventCollection],
    ) {
        use diesel::pg::upsert::excluded;
        diesel::insert_into(historical_event_collections::table)
            .values(historical_event_collections)
            .on_conflict((
                historical_event_collections::id,
                historical_event_collections::world_id,
            ))
            .do_update()
            .set((
                historical_event_collections::type_
                    .eq(excluded(historical_event_collections::type_)),
                historical_event_collections::start_year
                    .eq(excluded(historical_event_collections::start_year)),
                historical_event_collections::start_seconds72
                    .eq(excluded(historical_event_collections::start_seconds72)),
                historical_event_collections::end_year
                    .eq(excluded(historical_event_collections::end_year)),
                historical_event_collections::end_seconds72
                    .eq(excluded(historical_event_collections::end_seconds72)),
            ))
            .execute(conn)
            .expect("Error saving historical_event_collections");
    }

    #[cfg(not(feature = "postgres"))]
    fn insert_into_db(
        conn: &DbConnection,
        historical_event_collections: &[HistoricalEventCollection],
    ) {
        diesel::insert_into(historical_event_collections::table)
            .values(historical_event_collections)
            .execute(conn)
            .expect("Error saving historical_event_collections");
    }

    fn find_db_item(
        conn: &DbConnection,
        id_filter: HashMap<String, i32>,
    ) -> Result<Option<HistoricalEventCollection>, Error> {
        use crate::schema::historical_event_collections::dsl::*;
        let query = historical_event_collections;
        let query = query.filter(world_id.eq(id_filter.get("world_id").unwrap_or(&0)));
        let query = query.filter(id.eq(id_filter.get("id").unwrap_or(&0)));
        Ok(query.first::<HistoricalEventCollection>(conn).optional()?)
    }

    fn find_db_list(
        conn: &DbConnection,
        id_filter: HashMap<String, i32>,
        _string_filter: HashMap<String, String>,
        offset: i64,
        limit: i64,
        order: Option<OrderTypes>,
        order_by: Option<String>,
        id_list: Option<Vec<i32>>,
    ) -> Result<Vec<HistoricalEventCollection>, Error> {
        use crate::schema::historical_event_collections::dsl::*;
        let (order_by, asc) = Self::get_order(order, order_by);
        let query = historical_event_collections.limit(limit).offset(offset);
        let query = query.filter(world_id.eq(id_filter.get("world_id").unwrap_or(&0)));
        optional_filter! {
            query, id_filter,
            id_list => id,
            [
                "id" => id,
            ],
            {Ok(order_by!{
                order_by, asc, query, conn,
                "id" => id,
                "type" => type_,
                "start_year" => start_year,
                "start_seconds72" => start_seconds72,
                "end_year" => end_year,
                "end_seconds72" => end_seconds72,
            })},
        }
    }

    fn match_field_by(field: String) -> String {
        match field.as_ref() {
            "type" => "type",
            "start_year" => "start_year",
            "start_seconds72" => "start_seconds72",
            "end_year" => "end_year",
            "end_seconds72" => "end_seconds72",
            _ => "id",
        }
        .to_owned()
    }

    fn add_nested_items(
        conn: &DbConnection,
        db_list: &[HistoricalEventCollection],
        _core_list: Vec<df_st_core::HistoricalEventCollection>,
    ) -> Result<Vec<df_st_core::HistoricalEventCollection>, Error> {
        let world_id = match db_list.first() {
            Some(x) => x.world_id,
            None => 0,
        };
        // Add HistoricalEventAA
        let hec_a_c_list = HistoricalEventCollectionAC::belonging_to(db_list)
            .filter(crate::schema::historical_event_collections_a_c::world_id.eq(world_id))
            .load::<HistoricalEventCollectionAC>(conn)?
            .grouped_by(db_list);
        // Add HistoricalEventDZ
        let hec_d_z_list = HistoricalEventCollectionDZ::belonging_to(db_list)
            .filter(crate::schema::historical_event_collections_d_z::world_id.eq(world_id))
            .load::<HistoricalEventCollectionDZ>(conn)?
            .grouped_by(db_list);
        // Add HECRelatedID
        let he_id_list = HECHEID::belonging_to(db_list)
            .filter(crate::schema::hec_he_ids::world_id.eq(world_id))
            .load::<HECHEID>(conn)?
            .grouped_by(db_list);
        // Add HECRelatedID
        let hec_related_list = HECRelatedID::belonging_to(db_list)
            .filter(crate::schema::hec_related_ids::world_id.eq(world_id))
            .load::<HECRelatedID>(conn)?
            .grouped_by(db_list);
        // Add HECIndividualMerc
        let indiv_merc_list = HECIndividualMerc::belonging_to(db_list)
            .filter(crate::schema::hec_individual_mercs::world_id.eq(world_id))
            .load::<HECIndividualMerc>(conn)?
            .grouped_by(db_list);
        // Add HECNoncomHFID
        let noncom_hf_id_list = HECNoncomHFID::belonging_to(db_list)
            .filter(crate::schema::hec_noncom_hf_ids::world_id.eq(world_id))
            .load::<HECNoncomHFID>(conn)?
            .grouped_by(db_list);
        // Add HECOutcome
        let outcome_list = HECOutcome::belonging_to(db_list)
            .filter(crate::schema::hec_outcomes::world_id.eq(world_id))
            .load::<HECOutcome>(conn)?
            .grouped_by(db_list);
        // Add HECAttackingHFID
        let attack_hf_id_list = HECAttackingHFID::belonging_to(db_list)
            .filter(crate::schema::hec_attacking_hf_ids::world_id.eq(world_id))
            .load::<HECAttackingHFID>(conn)?
            .grouped_by(db_list);
        // Add HECDefendingHFID
        let defending_hf_id_list = HECDefendingHFID::belonging_to(db_list)
            .filter(crate::schema::hec_defending_hf_ids::world_id.eq(world_id))
            .load::<HECDefendingHFID>(conn)?
            .grouped_by(db_list);
        // Add HECASupportMercHFID
        let a_support_merc_hf_id_list = HECASupportMercHFID::belonging_to(db_list)
            .filter(crate::schema::hec_a_support_merc_hf_ids::world_id.eq(world_id))
            .load::<HECASupportMercHFID>(conn)?
            .grouped_by(db_list);
        // Add HECDSupportMercHFID
        let d_support_merc_hf_id_list = HECDSupportMercHFID::belonging_to(db_list)
            .filter(crate::schema::hec_d_support_merc_hf_ids::world_id.eq(world_id))
            .load::<HECDSupportMercHFID>(conn)?
            .grouped_by(db_list);

        // Merge all
        let mut core_list: Vec<df_st_core::HistoricalEventCollection> = Vec::new();
        for (index, hec) in db_list.iter().enumerate() {
            let mut core_hec = df_st_core::HistoricalEventCollection::new();
            core_hec.add_missing_data(hec);
            let hec_a_c = hec_a_c_list.get(index).unwrap().get(0).unwrap();
            core_hec.add_missing_data(hec_a_c);
            let hec_d_z = hec_d_z_list.get(index).unwrap().get(0).unwrap();
            core_hec.add_missing_data(hec_d_z);

            for he_id in he_id_list.get(index).unwrap() {
                core_hec.he_ids.push(he_id.he_id);
            }
            for hec_id in hec_related_list.get(index).unwrap() {
                core_hec.hec_ids.push(hec_id.hec_id);
            }
            for indiv_merc in indiv_merc_list.get(index).unwrap() {
                core_hec.individual_merc.push(indiv_merc.individual_merc);
            }
            for noncom_hf_id in noncom_hf_id_list.get(index).unwrap() {
                core_hec.noncom_hf_id.push(noncom_hf_id.noncom_hf_id);
            }
            for outcome in outcome_list.get(index).unwrap() {
                core_hec.outcome.push(outcome.outcome.clone());
            }
            for attack_hf_id in attack_hf_id_list.get(index).unwrap() {
                core_hec.attacking_hf_id.push(attack_hf_id.attacking_hf_id);
            }
            for defending_hf_id in defending_hf_id_list.get(index).unwrap() {
                core_hec
                    .defending_hf_id
                    .push(defending_hf_id.defending_hf_id);
            }
            for support_merc in a_support_merc_hf_id_list.get(index).unwrap() {
                core_hec
                    .a_support_merc_hf_id
                    .push(support_merc.a_support_merc_hf_id);
            }
            for support_merc in d_support_merc_hf_id_list.get(index).unwrap() {
                core_hec
                    .d_support_merc_hf_id
                    .push(support_merc.d_support_merc_hf_id);
            }

            core_list.push(core_hec);
        }

        Ok(core_list)
    }

    fn get_count_from_db(
        conn: &DbConnection,
        id_filter: HashMap<String, i32>,
        _string_filter: HashMap<String, String>,
        offset: u32,
        limit: u32,
        group_by_opt: Option<String>,
        id_list: Option<Vec<i32>>,
    ) -> Result<Vec<ItemCount>, Error> {
        use crate::schema::historical_event_collections::dsl::*;
        let query = historical_event_collections
            .limit(limit as i64)
            .offset(offset as i64);
        let query = query.filter(world_id.eq(id_filter.get("world_id").unwrap_or(&0)));
        optional_filter! {
            query, id_filter,
            id_list => id,
            [
                "id" => id,
            ],
            {group_by!{
                group_by_opt, query, conn,
                "id" => {id: i32},
                "type" => {type_: Option<String>},
                "start_year" => {start_year: Option<i32>},
                "start_seconds72" => {start_seconds72: Option<i32>},
                "end_year" => {end_year: Option<i32>},
                "end_seconds72" => {end_seconds72: Option<i32>},
            };},
        };
    }
}

/// From Core to DB
impl Filler<HistoricalEventCollection, df_st_core::HistoricalEventCollection>
    for HistoricalEventCollection
{
    fn add_missing_data(&mut self, source: &df_st_core::HistoricalEventCollection) {
        self.id.add_missing_data(&source.id);
        self.type_.add_missing_data(&source.type_);
        self.start_year.add_missing_data(&source.start_year);
        self.start_seconds72
            .add_missing_data(&source.start_seconds72);
        self.end_year.add_missing_data(&source.end_year);
        self.end_seconds72.add_missing_data(&source.end_seconds72);
    }
}

/// From DB to Core
impl Filler<df_st_core::HistoricalEventCollection, HistoricalEventCollection>
    for df_st_core::HistoricalEventCollection
{
    fn add_missing_data(&mut self, source: &HistoricalEventCollection) {
        self.id.add_missing_data(&source.id);
        self.type_.add_missing_data(&source.type_);
        self.start_year.add_missing_data(&source.start_year);
        self.start_seconds72
            .add_missing_data(&source.start_seconds72);
        self.end_year.add_missing_data(&source.end_year);
        self.end_seconds72.add_missing_data(&source.end_seconds72);
    }
}

impl PartialEq<HistoricalEventCollection> for df_st_core::HistoricalEventCollection {
    fn eq(&self, other: &HistoricalEventCollection) -> bool {
        self.id == other.id
    }
}

impl PartialEq<df_st_core::HistoricalEventCollection> for HistoricalEventCollection {
    fn eq(&self, other: &df_st_core::HistoricalEventCollection) -> bool {
        self.id == other.id
    }
}