4 extern crate diesel_derive_newtype;
6 extern crate lazy_static;
7 // this is used in tests
8 #[allow(unused_imports)]
10 extern crate diesel_migrations;
12 extern crate strum_macros;
21 pub type DbPool = diesel::r2d2::Pool<diesel::r2d2::ConnectionManager<diesel::PgConnection>>;
23 use crate::newtypes::DbUrl;
24 use chrono::NaiveDateTime;
25 use diesel::{Connection, PgConnection};
26 use lemmy_utils::ApiError;
28 use serde::{Deserialize, Serialize};
29 use std::{env, env::VarError};
32 pub fn get_database_url_from_env() -> Result<String, VarError> {
33 env::var("LEMMY_DATABASE_URL")
36 #[derive(EnumString, ToString, Debug, Serialize, Deserialize, Clone, Copy)]
50 #[derive(EnumString, ToString, Debug, Serialize, Deserialize, Clone, Copy)]
51 pub enum ListingType {
58 #[derive(EnumString, ToString, Debug, Serialize, Deserialize, Clone, Copy)]
68 pub fn from_opt_str_to_opt_enum<T: std::str::FromStr>(opt: &Option<String>) -> Option<T> {
69 opt.as_ref().map(|t| T::from_str(t).ok()).flatten()
72 pub fn fuzzy_search(q: &str) -> String {
73 let replaced = q.replace("%", "\\%").replace("_", "\\_").replace(" ", "%");
74 format!("%{}%", replaced)
77 pub fn limit_and_offset(page: Option<i64>, limit: Option<i64>) -> (i64, i64) {
78 let page = page.unwrap_or(1);
79 let limit = limit.unwrap_or(10);
80 let offset = limit * (page - 1);
84 pub fn is_email_regex(test: &str) -> bool {
85 EMAIL_REGEX.is_match(test)
88 pub fn diesel_option_overwrite(opt: &Option<String>) -> Option<Option<String>> {
90 // An empty string is an erase
92 if !unwrapped.eq("") {
93 Some(Some(unwrapped.to_owned()))
102 pub fn diesel_option_overwrite_to_url(
103 opt: &Option<String>,
104 ) -> Result<Option<Option<DbUrl>>, ApiError> {
105 match opt.as_ref().map(|s| s.as_str()) {
106 // An empty string is an erase
107 Some("") => Ok(Some(None)),
108 Some(str_url) => match Url::parse(str_url) {
109 Ok(url) => Ok(Some(Some(url.into()))),
110 Err(e) => Err(ApiError::err("invalid_url", e)),
118 pub fn establish_unpooled_connection() -> PgConnection {
119 let db_url = match get_database_url_from_env() {
122 "Failed to read database URL from env var LEMMY_DATABASE_URL: {}",
127 PgConnection::establish(&db_url).unwrap_or_else(|_| panic!("Error connecting to {}", db_url));
128 embedded_migrations::run(&conn).expect("load migrations");
132 pub fn naive_now() -> NaiveDateTime {
133 chrono::prelude::Utc::now().naive_utc()
137 static ref EMAIL_REGEX: Regex =
138 Regex::new(r"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$")
139 .expect("compile email regex");
143 use diesel::sql_types::*;
146 fn hot_rank(score: BigInt, time: Timestamp) -> Integer;
152 use super::{fuzzy_search, *};
153 use crate::is_email_regex;
156 fn test_fuzzy_search() {
157 let test = "This %is% _a_ fuzzy search";
160 "%This%\\%is\\%%\\_a\\_%fuzzy%search%".to_string()
166 assert!(is_email_regex("gush@gmail.com"));
167 assert!(!is_email_regex("nada_neutho"));
171 fn test_diesel_option_overwrite() {
172 assert_eq!(diesel_option_overwrite(&None), None);
173 assert_eq!(diesel_option_overwrite(&Some("".to_string())), Some(None));
175 diesel_option_overwrite(&Some("test".to_string())),
176 Some(Some("test".to_string()))
181 fn test_diesel_option_overwrite_to_url() {
182 assert!(matches!(diesel_option_overwrite_to_url(&None), Ok(None)));
184 diesel_option_overwrite_to_url(&Some("".to_string())),
188 diesel_option_overwrite_to_url(&Some("invalid_url".to_string())),
191 let example_url = "https://example.com";
193 diesel_option_overwrite_to_url(&Some(example_url.to_string())),
194 Ok(Some(Some(url))) if url == Url::parse(example_url).unwrap().into()