df_st_db 0.3.0-development-2

Database store and query implementation for the DF Storyteller project.
Documentation
use crate::db_object::{DBObject, MatchBy, OrderTypes};
use crate::df_world::{Artifact, DBDFWorld, Site};
use crate::schema::structure_copied_artifact_ids;
use crate::DbConnection;
use anyhow::Error;
use df_st_core::fillable::{Fillable, Filler};
use df_st_core::item_count::ItemCount;
use df_st_derive::{Fillable, Filler};
use diesel::expression_methods::ExpressionMethods;
use diesel::prelude::*;
use diesel::query_dsl::RunQueryDsl;
use std::collections::HashMap;
use std::hash::{Hash, Hasher};

#[derive(
    Clone, Debug, Identifiable, Associations, Filler, Queryable, Insertable, Fillable, Default,
)]
#[table_name = "structure_copied_artifact_ids"]
#[primary_key(site_id, structure_local_id, copied_artifact_id)]
#[belongs_to(Site, foreign_key = "site_id")]
#[belongs_to(Artifact, foreign_key = "copied_artifact_id")]
pub struct StructureCopiedArtifactID {
    pub site_id: i32,
    pub structure_local_id: i32,
    pub copied_artifact_id: i32,
    pub world_id: i32,
}

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

// There is no core variant of this item, so implement it for itself.
impl DBObject<StructureCopiedArtifactID, StructureCopiedArtifactID> for StructureCopiedArtifactID {
    fn add_missing_data_advanced(_core_world: &df_st_core::DFWorld, _world: &mut DBDFWorld) {
        // Nothing to add
    }

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

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

    /// Get a list of StructureCopiedArtifactID from the database
    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<StructureCopiedArtifactID>, Error> {
        use crate::schema::structure_copied_artifact_ids::dsl::*;
        let (order_by, asc) = Self::get_order(order, order_by);
        let query = structure_copied_artifact_ids.limit(limit).offset(offset);
        let query = query.filter(world_id.eq(id_filter.get("world_id").unwrap_or(&0)));
        optional_filter! {
            query, id_filter,
            [
                "site_id" => site_id,
                "structure_local_id" => structure_local_id,
                "copied_artifact_id" => copied_artifact_id,
            ],
            {Ok(order_by!{
                order_by, asc, query, conn,
                "site_id" => site_id,
                "structure_local_id" => structure_local_id,
                "copied_artifact_id" => copied_artifact_id,
            })},
        }
    }

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

    fn match_field_by(_match_by: MatchBy) -> Vec<&'static str> {
        vec!["site_id", "structure_local_id", "copied_artifact_id"]
    }

    fn add_nested_items(
        _conn: &DbConnection,
        _db_list: &[StructureCopiedArtifactID],
        core_list: Vec<StructureCopiedArtifactID>,
    ) -> Result<Vec<StructureCopiedArtifactID>, Error> {
        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::structure_copied_artifact_ids::dsl::*;
        let query = structure_copied_artifact_ids
            .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,
            [
                "site_id" => site_id,
                "structure_local_id" => structure_local_id,
                "copied_artifact_id" => copied_artifact_id,
            ],
            {group_by!{
                group_by_opt, query, conn,
                "site_id" => {site_id: i32},
                "structure_local_id" => {structure_local_id: i32},
                "copied_artifact_id" => {copied_artifact_id: i32},
            };},
        };
    }
}

impl PartialEq for StructureCopiedArtifactID {
    fn eq(&self, other: &Self) -> bool {
        self.site_id == other.site_id
            && self.structure_local_id == other.structure_local_id
            && self.copied_artifact_id == other.copied_artifact_id
    }
}

impl Hash for StructureCopiedArtifactID {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.site_id.hash(state);
        self.structure_local_id.hash(state);
        self.copied_artifact_id.hash(state);
    }
}