Merge branch '28-db-lib' into develop
						commit
						5b0e595253
					
				|  | @ -19,6 +19,14 @@ test = true | |||
| bench = true | ||||
| doc = true | ||||
| doctest = true | ||||
| 
 | ||||
| [[bin]] | ||||
| name = "populate_ivago" | ||||
| path = "src/populate_ivago.rs" | ||||
| test = false | ||||
| bench = false | ||||
| doc = false | ||||
| doctest = false | ||||
|   | ||||
| [dependencies] | ||||
| rocket = "0.4.7" | ||||
|  |  | |||
|  | @ -2,4 +2,4 @@ | |||
| # see diesel.rs/guides/configuring-diesel-cli | ||||
| 
 | ||||
| [print_schema] | ||||
| file = "src/schema.rs" | ||||
| file = "src/fej/schema.rs" | ||||
|  |  | |||
|  | @ -1,2 +1,2 @@ | |||
| -- This file should undo anything in `up.sql` | ||||
| DROP SCHEMA ivago CASCADE; | ||||
| DROP table ivago_streets; | ||||
|  |  | |||
|  | @ -1,7 +1,4 @@ | |||
| -- Your SQL goes here | ||||
| CREATE SCHEMA ivago; | ||||
| 
 | ||||
| CREATE TABLE ivago.streets ( | ||||
| CREATE TABLE ivago_streets ( | ||||
|     name TEXT NOT NULL, | ||||
|     city TEXT NOT NULL, | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ use rocket::http::Status; | |||
| pub enum FejError { | ||||
|     InvalidArgument, | ||||
|     FailedRequest, | ||||
|     DatabaseError, | ||||
| } | ||||
| 
 | ||||
| // I'd love to move this over to the server binary, but right now, error E0117 is making that
 | ||||
|  | @ -17,6 +18,7 @@ impl From<FejError> for Status { | |||
|         match err { | ||||
|             FejError::InvalidArgument => Status::BadRequest, | ||||
|             FejError::FailedRequest => Status::InternalServerError, | ||||
|             FejError::DatabaseError => Status::InternalServerError, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -33,3 +35,9 @@ impl From<chrono::ParseError> for FejError { | |||
|         FejError::InvalidArgument | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<diesel::result::Error> for FejError { | ||||
|     fn from(_: diesel::result::Error) -> FejError { | ||||
|         FejError::DatabaseError | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,12 @@ | |||
| use super::Street; | ||||
| use crate::errors::FejError; | ||||
| use crate::schema::ivago_streets::dsl::*; | ||||
| use diesel::prelude::*; | ||||
| use diesel::PgConnection; | ||||
| 
 | ||||
| pub fn search_streets(db_con: &PgConnection, search_term: &str) -> Result<Vec<Street>, FejError> { | ||||
|     Ok(ivago_streets | ||||
|         .filter(name.ilike(format!("%{}%", search_term))) | ||||
|         .or_filter(city.ilike(format!("%{}%", search_term))) | ||||
|         .load(db_con)?) | ||||
| } | ||||
|  | @ -6,6 +6,7 @@ use std::collections::HashMap; | |||
| use std::convert::{From, TryFrom}; | ||||
| 
 | ||||
| mod basic_date; | ||||
| pub mod db; | ||||
| mod pickup_time; | ||||
| mod street; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| use crate::schema::ivago_streets; | ||||
| use diesel::{Insertable, Queryable}; | ||||
| use regex::Regex; | ||||
| use rocket::http::RawStr; | ||||
| use rocket::request::FromFormValue; | ||||
|  | @ -5,6 +7,8 @@ use serde::ser::{Serialize, SerializeStruct, Serializer}; | |||
| use std::convert::TryFrom; | ||||
| 
 | ||||
| /// Represents a street in a given city
 | ||||
| #[derive(Queryable, Insertable)] | ||||
| #[table_name = "ivago_streets"] | ||||
| pub struct Street { | ||||
|     name: String, | ||||
|     city: String, | ||||
|  |  | |||
|  | @ -1,7 +1,10 @@ | |||
| #![feature(proc_macro_hygiene, decl_macro)] | ||||
| #[macro_use] | ||||
| extern crate diesel; | ||||
| 
 | ||||
| // Route modules
 | ||||
| pub mod ivago; | ||||
| 
 | ||||
| // Helper modules
 | ||||
| pub mod errors; | ||||
| 
 | ||||
| pub mod schema; | ||||
|  |  | |||
|  | @ -0,0 +1,6 @@ | |||
| table! { | ||||
|     ivago_streets (name, city) { | ||||
|         name -> Text, | ||||
|         city -> Text, | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,19 @@ | |||
| use diesel::{insert_into, Connection, PgConnection, RunQueryDsl}; | ||||
| use fej::ivago::search_streets; | ||||
| use fej::schema::ivago_streets::dsl::*; | ||||
| 
 | ||||
| const ABC: &str = "abcdefghijklmnopqrstuvwxyz"; | ||||
| 
 | ||||
| fn main() { | ||||
|     let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set"); | ||||
| 
 | ||||
|     let db_conn = PgConnection::establish(&database_url) | ||||
|         .expect(&format!("Error connecting to {}", database_url)); | ||||
| 
 | ||||
|     // Doing this linearly is good enough I'd say
 | ||||
|     for c in ABC.chars() { | ||||
|         if let Ok(streets) = search_streets(&c.to_string()) { | ||||
|             insert_into(ivago_streets).values(streets).execute(&db_conn); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -47,7 +47,7 @@ embed_migrations!(); | |||
| 
 | ||||
| // This defines a connection to the database
 | ||||
| #[database("postgres_fej")] | ||||
| struct FejDbConn(diesel::PgConnection); | ||||
| pub struct FejDbConn(diesel::PgConnection); | ||||
| 
 | ||||
| // I'd like to thank Stackoverflow for helping me with this
 | ||||
| // https://stackoverflow.com/questions/61047355/how-to-run-diesel-migration-with-rocket-in-production
 | ||||
|  | @ -55,7 +55,7 @@ fn run_db_migrations(rocket: Rocket) -> Result<Rocket, Rocket> { | |||
|     let conn = FejDbConn::get_one(&rocket).expect("database connection"); | ||||
|     match embedded_migrations::run(&*conn) { | ||||
|         Ok(()) => Ok(rocket), | ||||
|         Err(e) => Err(rocket), | ||||
|         Err(_) => Err(rocket), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,6 @@ | |||
| use fej::ivago::{get_pickup_times, search_streets, BasicDate, PickupTime, Street}; | ||||
| use crate::FejDbConn; | ||||
| use fej::ivago::db::search_streets; | ||||
| use fej::ivago::{get_pickup_times, BasicDate, PickupTime, Street}; | ||||
| use rocket::http::Status; | ||||
| use rocket_contrib::json::Json; | ||||
| 
 | ||||
|  | @ -9,8 +11,8 @@ use rocket_contrib::json::Json; | |||
| ///
 | ||||
| /// * `search_term` - Search term to use to look for streets
 | ||||
| #[get("/search?<q>")] | ||||
| pub fn route_search_streets(q: String) -> Result<Json<Vec<Street>>, Status> { | ||||
|     Ok(Json(search_streets(q.as_str())?)) | ||||
| pub fn route_search_streets(db_conn: FejDbConn, q: String) -> Result<Json<Vec<Street>>, Status> { | ||||
|     Ok(Json(search_streets(&db_conn.0, q.as_str())?)) | ||||
| } | ||||
| 
 | ||||
| /// Handles returning of pickup times for a specific address. It returns a list
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue