summaryrefslogtreecommitdiff
path: root/scripts/update-schema-models.bash
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/update-schema-models.bash')
-rw-r--r--scripts/update-schema-models.bash95
1 files changed, 95 insertions, 0 deletions
diff --git a/scripts/update-schema-models.bash b/scripts/update-schema-models.bash
new file mode 100644
index 0000000..f91f043
--- /dev/null
+++ b/scripts/update-schema-models.bash
@@ -0,0 +1,95 @@
+#!/bin/bash
+set -euo pipefail
+tmp="$(mktemp -d)"
+trap 'rm -rf -- "$tmp"' EXIT
+
+# deps
+hash sqlite3 diesel diesel_ext rustfmt
+
+gen_route() {
+ local upper="$1"
+ local lower="$(sed 's/[[:upper:]]/_&/g;s/^_//' <<<"$upper" | tr '[:upper:]' '[:lower:]')"
+cat <<EOF
+
+#[put("/$lower", data = "<input>")]
+async fn put_$lower(db: Db, input: InOut<$upper>) -> Result<Created<InOut<$upper>>> {
+ let data = input.clone();
+ db.run(move |conn| {
+ diesel::insert_into(${lower}s::table)
+ .values(&data)
+ .execute(conn)
+ })
+ .await?;
+ Ok(Created::new("/").body(input))
+}
+
+#[get("/$lower/<id>")]
+async fn get_$lower(db: Db, id: i64) -> Option<InOut<$upper>> {
+ db.run(move |conn| ${lower}s::table.filter(${lower}s::id.eq(id)).first(conn))
+ .await
+ .map(InOut)
+ .ok()
+}
+EOF
+}
+
+gen_routes() {
+ local db="$1"
+cat <<EOF
+use crate::diesel::ExpressionMethods;
+use crate::diesel::QueryDsl;
+use crate::diesel::RunQueryDsl;
+use rocket::Rocket;
+use rocket::response::{status::Created, Debug};
+use rocket::serde::json::Json as InOut;
+// use rocket::serde::msgpack::MsgPack as InOut;
+use rocket_sync_db_pools::database;
+
+#[database("$db")]
+pub struct Db(diesel::SqliteConnection);
+
+type Result<T, E = Debug<diesel::result::Error>> = std::result::Result<T, E>;
+EOF
+
+ grep 'pub struct' "$tmp"/model.rs | grep -v 'User' | while read -r _ _ name _; do
+ gen_route "$name"
+ done
+
+cat <<EOF
+
+pub fn mount_at(rocket: Rocket<rocket::Build>, path: &str) -> Rocket<rocket::Build> {
+ rocket.attach(Db::fairing()).mount(path, routes![
+EOF
+
+ grep 'pub struct' "$tmp"/model.rs | grep -v 'User' | while read -r _ _ name _; do
+ local lower="$(sed 's/[[:upper:]]/_&/g;s/^_//' <<<"$name" | tr '[:upper:]' '[:lower:]')"
+ printf ' %s,\n' "put_$lower"
+ printf ' %s,\n' "get_$lower"
+ done
+
+cat <<EOF
+ ])
+}
+EOF
+}
+
+for db in kanta; do
+ printf 'import: %s\n' db/"$db".sql
+ rm -f "$tmp"/tmp.sqlite
+ sqlite3 "$tmp"/tmp.sqlite < db/"$db".sql
+ diesel print-schema --database-url "$tmp"/tmp.sqlite |\
+ sed 's/Integer/BigInt/g' |\
+ sed 's/created_at -> Timestamp/created_at -> Nullable<Timestamp>/g' |\
+ sed 's/id -> BigInt/id -> Nullable<BigInt>/g' |\
+ sed 's/meta -> Text/meta -> Nullable<Text>/g' \
+ > "$tmp"/schema.rs
+ diesel_ext -s "$tmp"/schema.rs -m \
+ -d 'Serialize, Deserialize, Queryable, Insertable, Clone, Debug' \
+ -I 'rocket::serde::{Serialize, Deserialize}' |\
+ awk '/#\[derive/{print;print "#[serde(crate = \"rocket::serde\")]";next}1' \
+ > "$tmp"/model.rs
+ gen_routes "$db" | cat "$tmp"/schema.rs "$tmp"/model.rs - |\
+ grep -v '^// Generated by diesel_ext' |\
+ grep -v '^#!' > src/"$db".rs
+ rustfmt --edition 2021 src/"$db".rs
+done