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
|
set -euo pipefail
tmp="$(mktemp -d)"
trap 'rm -rf -- "$tmp"' EXIT
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
|