use anyhow::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)
}
async fn bump_counter(db: Client) -> Result<String> {
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?;
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),
];
let (airport, country, city, latitude, longitude) =
*FAKE_LOCATIONS.choose(&mut rand::thread_rng()).unwrap();
db.batch([
Statement::with_args(
"INSERT OR IGNORE INTO counter VALUES (?, ?, 0)",
&[country, city],
),
Statement::with_args(
"UPDATE counter SET value = value + 1 WHERE country = ? AND city = ?",
&[country, city],
),
Statement::with_args(
"INSERT OR IGNORE INTO coordinates VALUES (?, ?, ?)",
args!(latitude, longitude, airport),
),
])
.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() {
let db = Client::from_config(libsql_client::Config {
url: url::Url::parse("libsql://localhost:8080").unwrap(),
auth_token: None,
})
.await
.unwrap();
let response = bump_counter(db)
.await
.unwrap_or_else(|e| format!("Error: {e}"));
println!(
"Client parameters: backend={:?} url={:?}\n{response}",
std::env::var("LIBSQL_CLIENT_BACKEND"),
std::env::var("LIBSQL_CLIENT_URL")
);
}