-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathconnect_from_env.rs
83 lines (77 loc) · 3.01 KB
/
connect_from_env.rs
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
use libsql_client::Result;
use libsql_client::{args, Client, ResultSet, Statement};
use rand::prelude::SliceRandom;
fn result_to_string(query_result: ResultSet) -> Result<String> {
let mut ret = String::new();
let ResultSet { columns, rows, .. } = query_result;
for column in &columns {
ret += &format!("| {:16} |", column);
}
ret += "\n| -------------------------------------------------------- |\n";
for row in rows {
for cell in row.values {
ret += &format!("| {:16} |", cell);
}
ret += "\n";
}
Ok(ret)
}
// Bumps a counter for one of the geographic locations picked at random.
async fn bump_counter(db: Client) -> Result<String> {
// Recreate the tables if they do not exist yet
db.batch([
"CREATE TABLE IF NOT EXISTS counter(country TEXT, city TEXT, value, PRIMARY KEY(country, city)) WITHOUT ROWID",
"CREATE TABLE IF NOT EXISTS coordinates(lat INT, long INT, airport TEXT, PRIMARY KEY (lat, long))"
]).await?;
// For demo purposes, let's pick a pseudorandom location
const FAKE_LOCATIONS: &[(&str, &str, &str, f64, f64)] = &[
("WAW", "PL", "Warsaw", 52.22959, 21.0067),
("EWR", "US", "Newark", 42.99259, -81.3321),
("HAM", "DE", "Hamburg", 50.118801, 7.684300),
("HEL", "FI", "Helsinki", 60.3183, 24.9497),
("NSW", "AU", "Sydney", -33.9500, 151.1819),
];
for _ in 0..3 {
let (airport, country, city, latitude, longitude) =
*FAKE_LOCATIONS.choose(&mut rand::thread_rng()).unwrap();
let transaction = db.transaction().await?;
transaction
.execute(Statement::with_args(
"INSERT OR IGNORE INTO counter VALUES (?, ?, 0)",
// Parameters that have a single type can be passed as a regular slice
&[country, city],
))
.await?;
transaction
.execute(Statement::with_args(
"UPDATE counter SET value = value + 1 WHERE country = ? AND city = ?",
&[country, city],
))
.await?;
transaction
.execute(Statement::with_args(
"INSERT OR IGNORE INTO coordinates VALUES (?, ?, ?)",
// Parameters with different types can be passed to a convenience macro - args!()
args!(latitude, longitude, airport),
))
.await?;
transaction.commit().await?;
}
let counter_response = db.execute("SELECT * FROM counter").await?;
let scoreboard = result_to_string(counter_response)?;
let html = format!("Scoreboard:\n{scoreboard}");
Ok(html)
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
let db = Client::from_env().await.unwrap();
let response = bump_counter(db)
.await
.unwrap_or_else(|e| format!("Error: {e}"));
println!(
"Client parameters: url={:?} token={:?}\n{response}",
std::env::var("LIBSQL_CLIENT_URL"),
std::env::var("LIBSQL_CLIENT_TOKEN"),
);
}