Initial Commit
This commit is contained in:
parent
b7f5c4370c
commit
643c42d970
10 changed files with 2347 additions and 0 deletions
1
.env
Normal file
1
.env
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
DATABASE_URL=sqlite://db/huellas.db
|
||||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
/db
|
||||||
2095
Cargo.lock
generated
Normal file
2095
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
18
Cargo.toml
Normal file
18
Cargo.toml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
[package]
|
||||||
|
name = "huellas"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rocket = {version = "0.5.0-rc.2", features = ["json"]}
|
||||||
|
|
||||||
|
[dependencies.rocket_db_pools]
|
||||||
|
version = "0.1.0-rc.2"
|
||||||
|
features = ["sqlx_sqlite"]
|
||||||
|
|
||||||
|
[dependencies.sqlx]
|
||||||
|
version = "0.5.13"
|
||||||
|
default-features = false
|
||||||
|
features = ["macros", "offline", "migrate", "sqlite"]
|
||||||
2
Rocket.toml
Normal file
2
Rocket.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
[default.databases.db]
|
||||||
|
url = "sqlite://db/huellas.db"
|
||||||
11
migrations/20220717192031_create_places_table.sql
Normal file
11
migrations/20220717192031_create_places_table.sql
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
CREATE TABLE places (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name VARCHAR NOT NULL,
|
||||||
|
address VARCHAR NOT NULL,
|
||||||
|
open_hours VARCHAR NOT NULL,
|
||||||
|
icon VARCHAR NOT NULL,
|
||||||
|
description VARCHAR NOT NULL,
|
||||||
|
longitude REAL NOT NULL,
|
||||||
|
latitude REAL NOT NULL,
|
||||||
|
active BOOLEAN NOT NULL DEFAULT TRUE
|
||||||
|
);
|
||||||
83
sqlx-data.json
Normal file
83
sqlx-data.json
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
{
|
||||||
|
"db": "SQLite",
|
||||||
|
"6816e8476ded94e1537b3e2ef262260fb4dd8993e4335c25a96a2463eda7f1f0": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "INSERT INTO places (name, address, open_hours, icon, description, longitude, latitude) VALUES (?, ?, ?, ?, ?, ?, ?)"
|
||||||
|
},
|
||||||
|
"8f8e9058b89c1f10360e08f8733c75e6ea2e8c15ff2c1e8a9f4a8ecd6e778642": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Int64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "address",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "open_hours",
|
||||||
|
"ordinal": 3,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "icon",
|
||||||
|
"ordinal": 4,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "description",
|
||||||
|
"ordinal": 5,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "longitude",
|
||||||
|
"ordinal": 6,
|
||||||
|
"type_info": "Float"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "latitude",
|
||||||
|
"ordinal": 7,
|
||||||
|
"type_info": "Float"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "SELECT id, name, address, open_hours, icon, description, longitude, latitude FROM places WHERE active = TRUE"
|
||||||
|
},
|
||||||
|
"af66ec71413501f84c7f4cb0dd732c8ebfcd3da36a5f1177918c2277a8674c28": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "UPDATE places SET active = FALSE WHERE id = ?"
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/main.rs
Normal file
17
src/main.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#[macro_use]
|
||||||
|
extern crate rocket;
|
||||||
|
|
||||||
|
mod place;
|
||||||
|
mod routes;
|
||||||
|
|
||||||
|
#[get("/")]
|
||||||
|
fn index() -> &'static str {
|
||||||
|
"Hello, world!"
|
||||||
|
}
|
||||||
|
|
||||||
|
#[launch]
|
||||||
|
fn rocket() -> _ {
|
||||||
|
rocket::build()
|
||||||
|
.mount("/", routes![index])
|
||||||
|
.attach(routes::stage())
|
||||||
|
}
|
||||||
26
src/place.rs
Normal file
26
src/place.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
use rocket::serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(crate = "rocket::serde")]
|
||||||
|
pub struct Place {
|
||||||
|
pub id: Option<i64>,
|
||||||
|
pub name: String,
|
||||||
|
pub address: String,
|
||||||
|
pub open_hours: String,
|
||||||
|
pub icon: String,
|
||||||
|
pub description: String,
|
||||||
|
pub longitude: f32,
|
||||||
|
pub latitude: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(crate = "rocket::serde")]
|
||||||
|
pub struct UpdatePlace {
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub address: Option<String>,
|
||||||
|
pub open_hours: Option<String>,
|
||||||
|
pub icon: Option<String>,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub longitude: Option<f32>,
|
||||||
|
pub latitude: Option<f32>,
|
||||||
|
}
|
||||||
92
src/routes.rs
Normal file
92
src/routes.rs
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
use rocket::fairing::{self, AdHoc};
|
||||||
|
use rocket::response::status::Created;
|
||||||
|
use rocket::serde::json::Json;
|
||||||
|
use rocket::{Build, Rocket};
|
||||||
|
use rocket_db_pools::{Connection, Database};
|
||||||
|
|
||||||
|
use rocket::futures::stream::TryStreamExt;
|
||||||
|
|
||||||
|
use crate::place::{Place, UpdatePlace};
|
||||||
|
type Result<T, E = rocket::response::Debug<sqlx::Error>> = std::result::Result<T, E>;
|
||||||
|
|
||||||
|
#[derive(Database)]
|
||||||
|
#[database("db")]
|
||||||
|
struct Db(rocket_db_pools::sqlx::SqlitePool);
|
||||||
|
|
||||||
|
#[get("/places")]
|
||||||
|
async fn get_places(mut db: Connection<Db>) -> Result<Json<Vec<Place>>> {
|
||||||
|
let places = rocket_db_pools::sqlx::query!(
|
||||||
|
"SELECT id, name, address, open_hours, icon, description, longitude, latitude FROM places WHERE active = TRUE")
|
||||||
|
.fetch(&mut *db)
|
||||||
|
.map_ok(|p| Place {
|
||||||
|
id: Some(p.id),
|
||||||
|
name: p.name,
|
||||||
|
address: p.address,
|
||||||
|
open_hours: p.open_hours,
|
||||||
|
icon: p.icon,
|
||||||
|
description: p.description,
|
||||||
|
latitude: p.latitude,
|
||||||
|
longitude: p.longitude
|
||||||
|
})
|
||||||
|
.try_collect::<Vec<_>>()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(Json(places))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/places", format = "json", data = "<place>")]
|
||||||
|
async fn create_place(mut db: Connection<Db>, place: Json<Place>) -> Result<Created<Json<Place>>> {
|
||||||
|
::sqlx::query!(
|
||||||
|
"INSERT INTO places (name, address, open_hours, icon, description, longitude, latitude) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||||
|
place.name,
|
||||||
|
place.address,
|
||||||
|
place.open_hours,
|
||||||
|
place.icon,
|
||||||
|
place.description,
|
||||||
|
place.longitude,
|
||||||
|
place.latitude
|
||||||
|
)
|
||||||
|
.execute(&mut *db)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(Created::new("/places").body(place))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[patch("/places/<id>", format = "json", data = "<update_place>")]
|
||||||
|
fn update_place(id: i64, update_place: Json<UpdatePlace>) -> &'static str {
|
||||||
|
"Hello, world!"
|
||||||
|
}
|
||||||
|
|
||||||
|
#[delete("/places/<id>")]
|
||||||
|
async fn delete_place(mut db: Connection<Db>, id: i64) -> Result<Option<()>> {
|
||||||
|
let result = ::sqlx::query!("UPDATE places SET active = FALSE WHERE id = ?", id)
|
||||||
|
.execute(&mut *db)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok((result.rows_affected() == 1).then(|| ()))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run_migrations(rocket: Rocket<Build>) -> fairing::Result {
|
||||||
|
match Db::fetch(&rocket) {
|
||||||
|
Some(db) => match ::sqlx::migrate!("./migrations").run(&**db).await {
|
||||||
|
Ok(_) => Ok(rocket),
|
||||||
|
Err(e) => {
|
||||||
|
error!("Failed to initialize SQLx database: {}", e);
|
||||||
|
Err(rocket)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => Err(rocket),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stage() -> AdHoc {
|
||||||
|
AdHoc::on_ignite("SQLx Stage", |rocket| async {
|
||||||
|
rocket
|
||||||
|
.attach(Db::init())
|
||||||
|
.attach(AdHoc::try_on_ignite("SQLx Migrations", run_migrations))
|
||||||
|
.mount(
|
||||||
|
"/",
|
||||||
|
routes![create_place, get_places, update_place, delete_place],
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue