use serde_json::json;
#[tokio::test]
async fn sql_engine_round_trips_against_real_sqlite() {
let dir = tempfile::tempdir().unwrap();
let database_url = format!("sqlite://{}/test.sqlite", dir.path().display());
larust_orm::connect(&database_url).await.unwrap();
let pool = larust_orm::pool().unwrap();
sqlx::query(
"CREATE TABLE posts_like (\
id INTEGER PRIMARY KEY AUTOINCREMENT, \
title TEXT NOT NULL, \
views INTEGER NOT NULL DEFAULT 0, \
note TEXT)",
)
.execute(pool)
.await
.unwrap();
sqlx::query(
"CREATE TABLE post_tag_like (post_id INTEGER NOT NULL, tag_id INTEGER NOT NULL, \
PRIMARY KEY (post_id, tag_id), \
FOREIGN KEY (post_id) REFERENCES posts_like (id))",
)
.execute(pool)
.await
.unwrap();
sqlx::query("CREATE INDEX idx_post_tag_like_tag_id ON post_tag_like (tag_id)")
.execute(pool)
.await
.unwrap();
let tables = larust_db::sql::introspect::list_tables().await.unwrap();
assert_eq!(tables, vec!["post_tag_like", "posts_like"]);
let columns = larust_db::sql::introspect::table_columns("posts_like")
.await
.unwrap();
let by_name = |name: &str| columns.iter().find(|c| c.name == name).unwrap();
assert!(by_name("title").not_null);
assert!(!by_name("note").not_null);
assert_eq!(by_name("id").kind, sqlx::any::AnyTypeInfoKind::BigInt);
assert_eq!(by_name("title").kind, sqlx::any::AnyTypeInfoKind::Text);
assert_eq!(
larust_db::sql::introspect::primary_key_columns("posts_like")
.await
.unwrap(),
vec!["id"]
);
assert_eq!(
larust_db::sql::introspect::primary_key_columns("post_tag_like")
.await
.unwrap(),
vec!["post_id", "tag_id"]
);
larust_db::sql::mutate::insert_row(
"posts_like",
&columns,
&[
("title".to_string(), json!("Hello")),
("views".to_string(), json!(3)),
],
)
.await
.unwrap();
let rows = larust_db::sql::mutate::run_raw("SELECT * FROM posts_like")
.await
.unwrap();
assert_eq!(rows.len(), 1);
assert_eq!(rows[0]["title"], json!("Hello"));
assert_eq!(rows[0]["views"], json!(3));
assert_eq!(rows[0]["note"], serde_json::Value::Null);
let id = rows[0]["id"].clone();
larust_db::sql::mutate::update_row(
"posts_like",
&columns,
&[("id".to_string(), id.clone())],
&[("title".to_string(), json!("Updated"))],
)
.await
.unwrap();
let rows = larust_db::sql::mutate::run_raw("SELECT title FROM posts_like")
.await
.unwrap();
assert_eq!(rows[0]["title"], json!("Updated"));
larust_db::sql::mutate::delete_row("posts_like", &columns, &[("id".to_string(), id)])
.await
.unwrap();
let rows = larust_db::sql::mutate::run_raw("SELECT * FROM posts_like")
.await
.unwrap();
assert!(rows.is_empty());
larust_db::sql::mutate::insert_row(
"posts_like",
&columns,
&[("title".to_string(), json!("For the tag FK"))],
)
.await
.unwrap();
let fk_post_id = larust_db::sql::mutate::run_raw("SELECT id FROM posts_like")
.await
.unwrap()[0]["id"]
.clone();
let tag_columns = larust_db::sql::introspect::table_columns("post_tag_like")
.await
.unwrap();
larust_db::sql::mutate::insert_row(
"post_tag_like",
&tag_columns,
&[
("post_id".to_string(), fk_post_id.clone()),
("tag_id".to_string(), json!(2)),
],
)
.await
.unwrap();
let pk = vec![
("post_id".to_string(), fk_post_id),
("tag_id".to_string(), json!(2)),
];
larust_db::sql::mutate::delete_row("post_tag_like", &tag_columns, &pk)
.await
.unwrap();
let rows = larust_db::sql::mutate::run_raw("SELECT * FROM post_tag_like")
.await
.unwrap();
assert!(rows.is_empty());
let rows = larust_db::sql::mutate::run_raw("UPDATE posts_like SET views = 0")
.await
.unwrap();
assert!(rows.is_empty());
let indexes = larust_db::sql::introspect::list_indexes("post_tag_like")
.await
.unwrap();
assert_eq!(indexes.len(), 2);
assert!(indexes
.iter()
.any(|row| row["name"] == json!("idx_post_tag_like_tag_id")));
let no_indexes = larust_db::sql::introspect::list_indexes("posts_like")
.await
.unwrap();
assert!(no_indexes.is_empty());
let fks = larust_db::sql::introspect::list_foreign_keys("post_tag_like")
.await
.unwrap();
assert_eq!(fks.len(), 1);
assert_eq!(fks[0]["table"], json!("posts_like"));
assert_eq!(fks[0]["from"], json!("post_id"));
assert_eq!(fks[0]["to"], json!("id"));
let no_fks = larust_db::sql::introspect::list_foreign_keys("posts_like")
.await
.unwrap();
assert!(no_fks.is_empty());
}