extern crate fifthtry_serde_sqlite_jsonb as serde_sqlite_jsonb;
use std::collections::HashMap;
use rusqlite::{Connection, DatabaseName};
use serde_derive::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct Person {
id: i32,
name: String,
phone_numbers: Vec<PhoneNumber>,
is_champion: bool,
data: Vec<u8>,
}
#[derive(Debug, PartialEq, Deserialize, Serialize)]
enum PhoneNumber {
Internal(i32),
National(String),
International {
country_code: Option<i32>,
number: String,
},
Custom(Option<i32>, String),
}
#[test]
fn test_fetch_json_object() -> rusqlite::Result<()> {
let conn = Connection::open_in_memory()?;
let blob: Vec<u8> = conn.query_row(
r#"select jsonb('{
"id": 1,
"name": "John Doe",
"phone_numbers": [{"National": "1234"}],
"is_champion": true,
"data": [1, 2, 3]
}')"#,
[],
|row| row.get(0),
)?;
let person: Person = serde_sqlite_jsonb::from_slice(&blob).unwrap();
assert_eq!(
person,
Person {
id: 1,
name: "John Doe".to_string(),
phone_numbers: vec![PhoneNumber::National("1234".to_string())],
is_champion: true,
data: vec![1, 2, 3]
}
);
Ok(())
}
#[test]
fn test_large_object_as_blob() -> rusqlite::Result<()> {
let conn = Connection::open_in_memory()?;
conn.execute_batch(r#"
create table bigdata (
id integer primary key,
data blob
);
insert into bigdata (id, data) values (
42, -- the value of the integer primary key is the "rowid" in sqlite
jsonb_object(
'my long string', printf('%.*c', 10000000, 'x') -- 10Mb of 'x' characters
)
)"#,
)?;
let my_blob =
conn.blob_open(DatabaseName::Main, "bigdata", "data", 42, true)?;
let parsed: HashMap<String, String> =
serde_sqlite_jsonb::from_reader(my_blob).unwrap();
assert_eq!(
parsed,
[("my long string".into(), "x".repeat(10_000_000))]
.into_iter()
.collect()
);
Ok(())
}
#[test]
fn test_roadtrip() {
let my_obj: Vec<Person> = vec![
Person {
id: 1,
name: "John Doe".to_string(),
phone_numbers: vec![
PhoneNumber::International {
country_code: Some(33),
number: "1234".to_string(),
},
PhoneNumber::Custom(None, "5678".to_string()),
],
is_champion: true,
data: vec![1, 2, 3],
},
Person {
id: 2,
name: "Mister Smiley Baily 😊".to_string(),
phone_numbers: vec![],
is_champion: false,
data: (0..u8::MAX).collect(),
},
];
let encoded = serde_sqlite_jsonb::to_vec(&my_obj).unwrap();
assert_eq!(
my_obj,
serde_sqlite_jsonb::from_slice::<Vec<Person>>(&encoded).unwrap(),
"we can decode what we encoded"
);
let conn = Connection::open_in_memory().unwrap();
let went_through: Vec<u8> = conn
.query_row(
"SELECT jsonb(json(?))", [&encoded],
|row| row.get(0),
)
.unwrap();
let decoded: Vec<Person> =
serde_sqlite_jsonb::from_slice(&went_through).unwrap();
assert_eq!(my_obj, decoded, "went through sqlite and back");
}