Files
freeswitch_chris/did_router/src/database.rs

163 lines
3.8 KiB
Rust

use diesel::prelude::*;
use diesel::pg::PgConnection;
use diesel::result::Error;
use dotenvy::{from_path};
use std::env;
use std::path::Path;
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<String>,
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 {
let env_path = Path::new("/etc/did_router.conf");
from_path(env_path).expect("env file missed");
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<Did, Error> {
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<Did, Error> {
use crate::schema::dids::dsl::*;
let mut conn = connect();
let d = dids.filter(did_number.eq(did))
.first::<Did>(&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<Vec<Did>, 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<bool, Error> {
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::<i64>(&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"));
}
}