use diesel::prelude::*; use diesel::pg::PgConnection; use diesel::result::Error; use dotenvy::dotenv; use std::env; use serde::{Serialize}; use diesel_derive_enum::DbEnum; use std::str::FromStr; use strum_macros::EnumString; use crate::schema::dids; #[derive(Debug, PartialEq, DbEnum, Serialize, EnumString)] #[db_enum(existing_type_path = "crate::schema::sql_types::DidTargetType")] pub enum DidTargetType { #[db_enum(rename ="URL")] Url, #[db_enum(rename ="MOH")] Moh, #[db_enum(rename ="EXTERNAL_NUMBER")] ExternalNumber, #[db_enum(rename ="NO_SERVICE")] NoService, #[db_enum(rename ="NIGHT_MODE")] NightMode, #[db_enum(rename ="CUSTOME_MESSAGE")] CustomMessage } #[derive(Debug, Queryable, Selectable, Serialize, AsChangeset)] #[diesel(table_name = dids)] #[diesel(check_for_backend(diesel::pg::Pg))] pub struct Did { pub id: i32, pub did_number: String, pub target_type: DidTargetType, pub target: Option, pub active: bool, pub trunk: String, } #[derive(Insertable)] #[diesel(table_name = dids)] pub struct NewDid<'a> { pub did_number: &'a str, pub target_type: DidTargetType, pub target: Option<&'a str>, pub active: bool, pub trunk: &'a str, } pub fn connect() -> PgConnection { dotenv().ok(); let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); PgConnection::establish(&database_url) .unwrap_or_else(|_| panic!("Error connecting to database")) } pub fn get_did(a_id :i32) -> Result { use crate::schema::dids::dsl::*; let mut conn = connect(); let result = dids.find(a_id).first(&mut conn)?; Ok(result) } pub fn get_did_by(did: &str) -> Result { use crate::schema::dids::dsl::*; let mut conn = connect(); let d = dids.filter(did_number.eq(did)) .first::(&mut conn)?; Ok(d) } pub fn delete_did(i: i32) -> Result<(), Error> { use crate::schema::dids; use crate::schema::dids::columns::id; let mut conn = connect(); diesel::delete(dids::table) .filter(id.eq(i)) .execute(&mut conn)?; Ok(()) } pub fn update_did(d: Did)-> Result<(), Error> { use crate::schema::dids; use crate::schema::dids::dsl::*; let mut conn = connect(); diesel::update(dids::table) .filter(id.eq(d.id)) .set(d) .execute(&mut conn)?; Ok(()) } pub fn add_did(did_number: &str, target_type: &str, target: &str, active: bool, trunk: &str) -> Result<(), Error> { let mut conn = connect(); let new_did = NewDid { did_number: did_number, target_type: DidTargetType::from_str(target_type).unwrap(), target: Some(target), active: active, trunk: trunk, }; diesel::insert_into(dids::table) .values(&new_did) .execute(&mut conn)?; Ok(()) } pub fn list_did() ->Result, Error> { use crate::schema::dids::dsl::*; let mut conn = connect(); let res = dids .order_by(id.asc()) .load(&mut conn)?; Ok(res) } pub fn from_pbx(ipaddr: &str) -> Result { use crate::schema::dids::dsl::*; let pattern = format!("%{}%", ipaddr); let mut conn = connect(); let count = dids .filter(target.is_not_null().and(target.ilike(&pattern))) .count() .get_result::(&mut conn)?; Ok(count > 0) } #[cfg(test)] mod tests { use super::*; #[test] fn validate_from_pbx() { assert_eq!(Ok(true), from_pbx("172.16.0.213")); assert_eq!(Ok(true), from_pbx("172.16.0.215")); } #[test] fn validate_not_from_pbx() { assert_eq!(Ok(false), from_pbx("192.168.1.1")); } }