Add base app

This commit is contained in:
Kasper Juul Hermansen 2022-08-09 01:33:34 +02:00
commit 0430dee3bb
Signed by: kjuulh
GPG Key ID: 0F95C140730F2F23
11 changed files with 2113 additions and 0 deletions

4
.env Normal file
View File

@ -0,0 +1,4 @@
POSTGRES_DB=cibus
POSTGRES_USER=cibus
POSTGRES_PASSWORD=somenotverysecurepassword
DATABASE_URL="postgres://cibus:somenotverysecurepassword@localhost:5432/cibus"

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

1835
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

4
Cargo.toml Normal file
View File

@ -0,0 +1,4 @@
[workspace]
members = [
"cibus_bin"
]

15
cibus_bin/Cargo.toml Normal file
View File

@ -0,0 +1,15 @@
[package]
name = "cibus_bin"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
async-graphql = "4.0.6"
axum = "0.5.13"
tokio = {version="1.20.1", features=["full"]}
uuid = {version="1.1.2", features=["v4", "fast-rng"]}
sqlx = { version = "0.6", features = [ "runtime-tokio-rustls", "postgres", "migrate"] }
anyhow = "1.0.60"
dotenv = "0.15.0"

6
cibus_bin/build.rs Normal file
View File

@ -0,0 +1,6 @@
// generated by `sqlx migrate build-script`
fn main() {
// trigger recompilation when a new migration is added
println!("cargo:rerun-if-changed=migrations");
}

View File

@ -0,0 +1,4 @@
-- Add migration script here
CREATE TABLE IF NOT EXISTS events (
id BIGSERIAL PRIMARY KEY
);

View File

@ -0,0 +1 @@
-- Add migration script here

View File

@ -0,0 +1,67 @@
use async_graphql::{Context, EmptyMutation, EmptySubscription, Object, Schema, SimpleObject};
use uuid::Uuid;
pub type CibusSchema = Schema<QueryRoot, EmptyMutation, EmptySubscription>;
pub struct QueryRoot;
#[Object]
impl QueryRoot {
async fn get_upcoming(&self, ctx: &Context<'_>) -> Vec<Event> {
vec![Event::new(
None,
"Some-name".into(),
None,
None,
EventDate::new(2022, 08, 08, 23, 51),
)]
}
}
#[derive(SimpleObject)]
pub struct Event {
pub id: String,
pub name: String,
pub description: Option<Vec<String>>,
pub location: Option<String>,
pub date: EventDate,
}
impl Event {
pub fn new(
id: Option<String>,
name: String,
description: Option<Vec<String>>,
location: Option<String>,
date: EventDate,
) -> Self {
Self {
id: id.unwrap_or_else(|| Uuid::new_v4().to_string()),
name,
description,
location,
date,
}
}
}
#[derive(SimpleObject)]
pub struct EventDate {
pub year: u32,
pub month: u32,
pub day: u32,
pub hour: u32,
pub minute: u32,
}
impl EventDate {
pub fn new(year: u32, month: u32, day: u32, hour: u32, minute: u32) -> Self {
Self {
year,
month,
day,
hour,
minute,
}
}
}

56
cibus_bin/src/main.rs Normal file
View File

@ -0,0 +1,56 @@
mod graphql;
use std::env;
use async_graphql::{
http::{playground_source, GraphQLPlaygroundConfig},
EmptyMutation, EmptySubscription, Request, Response, Schema,
};
use axum::{
extract::Extension,
response::{Html, IntoResponse},
routing::get,
Json, Router,
};
use graphql::{CibusSchema, QueryRoot};
use sqlx::PgPool;
async fn graphql_handler(schema: Extension<CibusSchema>, req: Json<Request>) -> Json<Response> {
schema.execute(req.0).await.into()
}
async fn graphql_playground() -> impl IntoResponse {
Html(playground_source(GraphQLPlaygroundConfig::new("/")))
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Environment
println!("Loading dotenv");
dotenv::dotenv()?;
// Database
println!("Creating pool");
let pool = PgPool::connect(&env::var("DATABASE_URL")?).await?;
// Database Migrate
println!("Migrating db");
sqlx::migrate!("db/migrations").run(&pool).await?;
// Webserver
println!("Building schema");
let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription).finish();
println!("Building router");
let app = Router::new()
.route("/", get(graphql_playground).post(graphql_handler))
.layer(Extension(schema));
println!("Starting webserver");
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
Ok(())
}

120
local.sh Executable file
View File

@ -0,0 +1,120 @@
#!/bin/bash
name="cibus_postgres"
image="postgres"
version="latest"
ports="5432:5432"
db_name="cibus"
command=$1
arg_first=$2
already_running=$(docker ps | grep "$name")
bin_path="./cibus_bin"
env_path="$bin_path/.env"
echo "local environment : (command=$command)"
function log_out {
green="\033[0;32m"
no_color="\033[0m"
awk \
-v green=$green \
-v nocolor=$no_color \
-v name=$name \
'{ printf "\n%s%s: %s%s", green, name, nocolor, $0; fflush(); }'
}
function handle_commands {
if [[ $command == 'up' ]]
then
echo "starting local env"
echo
if [[ -n $already_running ]]
then
echo "docker image already running"
exit 2
fi
docker pull postgres:latest
docker run \
-p "$ports" \
-d \
--rm \
--env-file "$env_path" \
--name "$name" \
"$image:$version"
echo
echo "started local env"
elif [[ $command == 'down' ]]
then
echo "stopping local env"
echo
if [[ -n $already_running ]]
then
docker stop "$name" > /dev/null
echo "stopped and removed: $name"
else
echo "container: $name is not running"
fi
echo
echo "stopped local env"
elif [[ $command == 'logs' ]]
then
docker logs "$name" | log_out
elif [[ $command == 'connect_db' ]]
then
echo "connecting to db"
echo
if [[ -z $already_running ]]
then
echo "container not running cannot connect to db"
exit 1
fi
docker exec -it "$name" psql --user "$db_name" --db "$db_name"
echo
echo "exited db"
elif [[ $command == 'print_migration' ]]
then
echo "printing migrations"
echo
if [[ -z $already_running ]]
then
echo "container not running cannot check migrations"
exit 1
fi
echo "database"
docker exec -it "$name" psql --user "$db_name" --db "$db_name" -c "select version, description, success from _sqlx_migrations;"
echo "sqlx"
migration_path="$bin_path/db"
(cd "$migration_path" && sqlx migrate info)
echo
echo "exited db"
elif [[ $command == 'add_migration' ]]
then
echo "adding migration"
echo
migration_path="$bin_path/db"
(cd "$migration_path" && sqlx migrate add "$arg_first")
echo
echo "added migration"
else
echo "please provide a valid command (up / down)"
exit 1
fi
}
handle_commands
exit 0