tursodatabase / tursodatabase/libsql
Joint row deserialization into structs
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 17.2k
- Forks
- 531
- Avg merge
- 1h 12m
- Merged PRs (30d)
- 1
Description
I have this common use case where I join two tables and I want to deserialize a row into separate structs. However, each row cannot be easily deserialized into separate structs via from_row.
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, Default)]
pub struct User {
pub id: i32,
pub date: DateTime<Utc>,
pub group_id: i32,
}
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, Default)]
pub struct Group {
pub id: i32,
pub name: String,
}
The query is like
let rows = db_conn
.query(
"SELECT users.*, groups.*
FROM users
JOIN groups ON users.group_id = groups.id
WHERE users.user_id = ?1 LIMIT ?2
",
params![user_id.clone(), 10],
)
.await?;
while let Some(row) = rows.next().await? {
// there's no such thing:
let (users, group) = from_row<(User, Group)>(&row)?;
}
I have to do things like the following to be able to convert a Row into separate structs:
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, Default)]
pub struct UserWithGroup {
pub user: User,
pub group: Group,
}
// Implement from_row for UserWithGroup to deserialize from a database row
impl UserWithGroup {
pub fn from_row<'de>(row: &'de Row) -> Result<UserWithGroup, DeError> {
return Ok(Self {
user: User {
id: row.get(0).expect("id"),
date: DateTime::deserialize(
row.get_value(1).expect("date").into_deserializer(),
)?,
group_id: row.get(2).expect("group_id"),
},
group: Group {
id: row.get(3).expect("group_id"),
name: row.get(4).expect("name"),
},
});
}
}
To be able to do something like
while let Some(row) = rows.next().await? {
let users_with_group = UsersWithGroup::from_row(&row)?;
}
Is there a way to support from_row for the JOIN use cases maybe via tuples so that this manual work is not needed anymore?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the existing from_row and Row APIs used with rows.next() in the Rust database interface, then trace how joined-result columns are exposed. Done means a joined row can be converted into separate User and Group values through the requested tuple-style API without the manual UserWithGroup mapping.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, sqlite
- Domain
- databases
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100