summaryrefslogtreecommitdiff
path: root/scripts/update-schema-models.bash
blob: f91f043003df18ca483a27e5958dd915460d37bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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