Merge branch '28-db-lib' into develop
commit
5b0e595253
|
@ -20,6 +20,14 @@ bench = true
|
||||||
doc = true
|
doc = true
|
||||||
doctest = true
|
doctest = true
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "populate_ivago"
|
||||||
|
path = "src/populate_ivago.rs"
|
||||||
|
test = false
|
||||||
|
bench = false
|
||||||
|
doc = false
|
||||||
|
doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rocket = "0.4.7"
|
rocket = "0.4.7"
|
||||||
serde = "1.0.124"
|
serde = "1.0.124"
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
# see diesel.rs/guides/configuring-diesel-cli
|
# see diesel.rs/guides/configuring-diesel-cli
|
||||||
|
|
||||||
[print_schema]
|
[print_schema]
|
||||||
file = "src/schema.rs"
|
file = "src/fej/schema.rs"
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
-- This file should undo anything in `up.sql`
|
-- 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 TABLE ivago_streets (
|
||||||
CREATE SCHEMA ivago;
|
|
||||||
|
|
||||||
CREATE TABLE ivago.streets (
|
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
city TEXT NOT NULL,
|
city TEXT NOT NULL,
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ use rocket::http::Status;
|
||||||
pub enum FejError {
|
pub enum FejError {
|
||||||
InvalidArgument,
|
InvalidArgument,
|
||||||
FailedRequest,
|
FailedRequest,
|
||||||
|
DatabaseError,
|
||||||
}
|
}
|
||||||
|
|
||||||
// I'd love to move this over to the server binary, but right now, error E0117 is making that
|
// 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 {
|
match err {
|
||||||
FejError::InvalidArgument => Status::BadRequest,
|
FejError::InvalidArgument => Status::BadRequest,
|
||||||
FejError::FailedRequest => Status::InternalServerError,
|
FejError::FailedRequest => Status::InternalServerError,
|
||||||
|
FejError::DatabaseError => Status::InternalServerError,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,3 +35,9 @@ impl From<chrono::ParseError> for FejError {
|
||||||
FejError::InvalidArgument
|
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};
|
use std::convert::{From, TryFrom};
|
||||||
|
|
||||||
mod basic_date;
|
mod basic_date;
|
||||||
|
pub mod db;
|
||||||
mod pickup_time;
|
mod pickup_time;
|
||||||
mod street;
|
mod street;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use crate::schema::ivago_streets;
|
||||||
|
use diesel::{Insertable, Queryable};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rocket::http::RawStr;
|
use rocket::http::RawStr;
|
||||||
use rocket::request::FromFormValue;
|
use rocket::request::FromFormValue;
|
||||||
|
@ -5,6 +7,8 @@ use serde::ser::{Serialize, SerializeStruct, Serializer};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
/// Represents a street in a given city
|
/// Represents a street in a given city
|
||||||
|
#[derive(Queryable, Insertable)]
|
||||||
|
#[table_name = "ivago_streets"]
|
||||||
pub struct Street {
|
pub struct Street {
|
||||||
name: String,
|
name: String,
|
||||||
city: String,
|
city: String,
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
#![feature(proc_macro_hygiene, decl_macro)]
|
#[macro_use]
|
||||||
|
extern crate diesel;
|
||||||
|
|
||||||
// Route modules
|
// Route modules
|
||||||
pub mod ivago;
|
pub mod ivago;
|
||||||
|
|
||||||
// Helper modules
|
// Helper modules
|
||||||
pub mod errors;
|
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
|
// This defines a connection to the database
|
||||||
#[database("postgres_fej")]
|
#[database("postgres_fej")]
|
||||||
struct FejDbConn(diesel::PgConnection);
|
pub struct FejDbConn(diesel::PgConnection);
|
||||||
|
|
||||||
// I'd like to thank Stackoverflow for helping me with this
|
// 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
|
// 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");
|
let conn = FejDbConn::get_one(&rocket).expect("database connection");
|
||||||
match embedded_migrations::run(&*conn) {
|
match embedded_migrations::run(&*conn) {
|
||||||
Ok(()) => Ok(rocket),
|
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::http::Status;
|
||||||
use rocket_contrib::json::Json;
|
use rocket_contrib::json::Json;
|
||||||
|
|
||||||
|
@ -9,8 +11,8 @@ use rocket_contrib::json::Json;
|
||||||
///
|
///
|
||||||
/// * `search_term` - Search term to use to look for streets
|
/// * `search_term` - Search term to use to look for streets
|
||||||
#[get("/search?<q>")]
|
#[get("/search?<q>")]
|
||||||
pub fn route_search_streets(q: String) -> Result<Json<Vec<Street>>, Status> {
|
pub fn route_search_streets(db_conn: FejDbConn, q: String) -> Result<Json<Vec<Street>>, Status> {
|
||||||
Ok(Json(search_streets(q.as_str())?))
|
Ok(Json(search_streets(&db_conn.0, q.as_str())?))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles returning of pickup times for a specific address. It returns a list
|
/// Handles returning of pickup times for a specific address. It returns a list
|
||||||
|
|
Loading…
Reference in New Issue