Last active
January 17, 2022 16:20
-
-
Save rofrol/d86b59adcbca51f95fbf8847f5a039e0 to your computer and use it in GitHub Desktop.
Rust + Rocket + rust-postgres
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "hello-rocket" | |
version = "0.1.0" | |
authors = ["Roman Frołow"] | |
[dependencies] | |
rocket = "0.2.0" | |
rocket_codegen = "0.2.0" | |
postgres = "0.14" | |
serde = "0.9" | |
serde_json = "0.9" | |
serde_derive = "0.9" | |
rocket_contrib = "0.2.4" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(plugin)] | |
#![plugin(rocket_codegen)] | |
extern crate rocket; | |
extern crate postgres; | |
extern crate serde_json; | |
#[macro_use] | |
extern crate rocket_contrib; | |
#[macro_use] | |
extern crate serde_derive; | |
use postgres::{Connection, TlsMode}; | |
use rocket_contrib::{JSON, Value}; | |
#[get("/")] | |
fn index() -> &'static str { | |
"Hello, world!" | |
} | |
#[get("/<name>")] | |
fn name(name: &str) -> String { | |
format!("Hello, {}!", name) | |
} | |
#[derive(Serialize, Deserialize)] | |
struct UserInformation { | |
userId: i32, | |
name: String, | |
surname: String, | |
magicUrl: String, | |
notifications: Vec<Notification>, | |
} | |
#[derive(Serialize, Deserialize)] | |
struct Notification { | |
context: String, | |
status: bool, | |
} | |
#[get("/userInformation")] | |
fn user_information() -> JSON<UserInformation> { | |
let user_id = 1; | |
let conn = Connection::connect("postgres://postgres:p@localhost/algo2go", TlsMode::None) | |
.unwrap(); | |
let rows = &conn.query( | |
"SELECT \"userId\", name, surname, \"magicUrl\" FROM user_information where \"userId\" = $1", | |
&[&user_id]) | |
.unwrap(); | |
let row = rows.into_iter().next().unwrap(); | |
let mut notifications = Vec::new(); | |
for row in &conn.query( | |
"select context, status from user_information as u join notifications as n on n.\"userId\" \ | |
= u.\"userId\" and u.\"userId\" = $1", | |
&[&user_id]) | |
.unwrap() { | |
let notification = Notification { | |
context: row.get(0), | |
status: row.get(1), | |
}; | |
notifications.push(notification); | |
} | |
JSON(UserInformation { | |
userId: row.get(0), | |
name: row.get(1), | |
surname: row.get(2), | |
magicUrl: row.get(3), | |
notifications: notifications, | |
}) | |
} | |
#[derive(Serialize, Deserialize)] | |
struct DataSet { | |
id: i32, | |
name: String, | |
} | |
// create table data_sets ( | |
// name varchar, | |
// owner varchar, | |
// "ownerEmail" varchar, | |
// "releaseDate" varchar, | |
// "updatedDate" varchar, | |
// rating float, | |
// favourite bool, | |
// description varchar, | |
// usage varchar, | |
// "categoryId" integer, | |
// private bool, | |
// url varchar, | |
// id serial primary key | |
// ); | |
#[get("/dataSets")] | |
fn data_sets() -> JSON<Vec<DataSet>> { | |
let mut vec = Vec::new(); | |
let conn = Connection::connect("postgres://postgres:p@localhost/algo2go", TlsMode::None) | |
.unwrap(); | |
for row in &conn.query("SELECT id, name FROM data_sets", &[]) | |
.unwrap() { | |
let data_set = DataSet { | |
id: row.get(0), | |
name: row.get(1), | |
}; | |
// note: move occurs because `data_set` has type `DataSet`, | |
// which does not implement the `Copy` trait | |
println!("Found DataSet {}", &data_set.name); | |
vec.push(data_set); | |
} | |
JSON(vec) | |
} | |
#[derive(Serialize, Deserialize)] | |
struct DataSetWithComments { | |
id: i32, | |
name: String, | |
comments: Vec<Comment>, | |
} | |
#[derive(Serialize, Deserialize)] | |
struct Comment { | |
id: i32, | |
content: String, | |
userName: String, | |
userPhotoUrl: String, | |
date: String, | |
} | |
#[get("/dataSets/<url>")] | |
fn data_set(url: &str) -> JSON<DataSetWithComments> { | |
let conn = Connection::connect("postgres://postgres:p@localhost/algo2go", TlsMode::None) | |
.unwrap(); | |
let url2 = "dataSets/".to_owned() + url; | |
let rows = &conn.query("SELECT id, name FROM data_sets where url = $1", &[&url2]) | |
.unwrap(); | |
let row = rows.into_iter().next().unwrap(); | |
let data_set_id: i32 = row.get(0); | |
let mut comments = Vec::new(); | |
for row in | |
&conn.query("select c.id, content, \"userName\", \"userPhotoUrl\", date from comments as c \ | |
join data_sets as d on c.data_set_id = d.id and d.id = $1", | |
&[&data_set_id]) | |
.unwrap() { | |
let comment = Comment { | |
id: row.get(0), | |
content: row.get(1), | |
userName: row.get(2), | |
userPhotoUrl: row.get(3), | |
date: row.get(4), | |
}; | |
comments.push(comment); | |
} | |
JSON(DataSetWithComments { | |
id: row.get(0), | |
name: row.get(1), | |
comments: comments, | |
}) | |
} | |
#[derive(Serialize, Deserialize)] | |
struct Category { | |
id: i32, | |
title: String, | |
route: String, | |
count: i32, | |
contentUrl: String, | |
} | |
#[derive(Serialize, Deserialize)] | |
struct DataSetShort { | |
id: i32, | |
name: String, | |
description: String, | |
owner: String, | |
releaseDate: String, | |
rating: f32, | |
favourite: bool, | |
url: String, | |
} | |
#[get("/dataSetsCategories/<url>")] | |
fn data_set_category(url: &str) -> JSON<DataSetShort> { | |
let conn = Connection::connect("postgres://postgres:p@localhost/algo2go", TlsMode::None) | |
.unwrap(); | |
let url2 = "dataSetsCategories/".to_owned() + url; | |
let rows = &conn.query("select id from data_sets_categories where \"contentUrl\" = $1", | |
&[&url2]) | |
.unwrap(); | |
let row = rows.into_iter().next().unwrap(); | |
let data_set_category_id: i32 = row.get(0); | |
let mut dataSetShortRows = &conn.query("select d.id, name, SUBSTRING(description,0,100) as description, owner, \"releaseDate\", \ | |
rating, favourite, url from data_sets d join data_sets_in_categories di on d.id = di.data_sets_id \ | |
and di.data_sets_categories_id = $1", | |
&[&data_set_category_id]) | |
.unwrap(); | |
let dataSetShortRow = dataSetShortRows.into_iter().next().unwrap(); | |
JSON(DataSetShort { | |
id: dataSetShortRow.get(0), | |
name: dataSetShortRow.get(1), | |
description: dataSetShortRow.get(2), | |
owner: dataSetShortRow.get(3), | |
releaseDate: dataSetShortRow.get(4), | |
rating: dataSetShortRow.get(5), | |
favourite: dataSetShortRow.get(6), | |
url: dataSetShortRow.get(7), | |
}) | |
} | |
#[error(404)] | |
fn not_found() -> JSON<Value> { | |
JSON(json!({ | |
"status": "error", | |
"reason": "Resource was not found." | |
})) | |
} | |
fn main() { | |
rocket::ignite() | |
.mount("/", routes![index]) | |
.mount("/hello", routes![name]) | |
.mount("/api", | |
routes![user_information, data_sets, data_set, data_set_category]) | |
.catch(errors![not_found]) | |
.launch(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
write_mode = "overwrite" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment