commit 424a14337f392b3dedaf68c95051ab66d93ef8e7
parent a2f3e8c23e385234e7173baef4e8fc443a107c4b
Author: Silas Brack <silasbrack@gmail.com>
Date: Sun, 14 Jun 2026 15:03:31 +0200
perf: use RETURNING * for create_story, create_comment, create_user
Eliminates the separate read round-trip after each INSERT. The
created row is returned directly from the writer connection.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Diffstat:
1 file changed, 22 insertions(+), 24 deletions(-)
diff --git a/src/database.rs b/src/database.rs
@@ -389,18 +389,17 @@ impl Database {
let text = text.to_string();
let domain = domain.map(|s| s.to_string());
let language = language.to_string();
- let id = self.with_write(move |conn| {
+ self.with_write(move |conn| {
let published = now_epoch();
- conn.execute(
+ conn.query_row(
"INSERT INTO story (title, url, text, domain, published, language, created_by)
- VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)
+ RETURNING *",
params![title, url, text, domain, published, language, user_id],
- ).map_err(|e| AppError::Database(e.to_string()))?;
-
- Ok(conn.last_insert_rowid())
- }).await?;
- self.get_story(id).await?.ok_or_else(|| AppError::Database("Failed to retrieve created story".to_string()))
+ Self::row_to_story,
+ ).map_err(|e| AppError::Database(e.to_string()))
+ }).await
}
pub async fn update_story(
@@ -558,7 +557,7 @@ impl Database {
text: &str,
) -> Result<Comment, AppError> {
let text = text.to_string();
- let id = self.with_write(move |conn| {
+ self.with_write(move |conn| {
// Calculate path and depth
let (path, depth) = match parent_id {
Some(pid) => {
@@ -600,15 +599,14 @@ impl Database {
}
};
- conn.execute(
+ conn.query_row(
"INSERT INTO comment (story_id, parent_id, path, depth, text, created_by, created_at)
- VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)
+ RETURNING *",
params![story_id, parent_id, path, depth, text, user_id, now_epoch()],
- ).map_err(|e| AppError::Database(e.to_string()))?;
-
- Ok(conn.last_insert_rowid())
- }).await?;
- self.get_comment(id).await?.ok_or_else(|| AppError::Database("Failed to retrieve created comment".to_string()))
+ Self::row_to_comment,
+ ).map_err(|e| AppError::Database(e.to_string()))
+ }).await
}
pub async fn get_comment(&self, id: i64) -> Result<Option<Comment>, AppError> {
@@ -854,15 +852,15 @@ impl Database {
let password_hash = password_hash.to_string();
let username = username.to_string();
let verification_token = verification_token.map(|s| s.to_string());
- let id = self.with_write(move |conn| {
- conn.execute(
- "INSERT INTO user (email, password_hash, username, verification_token, created_at) VALUES (?1, ?2, ?3, ?4, ?5)",
+ self.with_write(move |conn| {
+ conn.query_row(
+ "INSERT INTO user (email, password_hash, username, verification_token, created_at)
+ VALUES (?1, ?2, ?3, ?4, ?5)
+ RETURNING *",
params![email, password_hash, username, verification_token, now_epoch()],
- ).map_err(|e| AppError::Database(e.to_string()))?;
-
- Ok(conn.last_insert_rowid())
- }).await?;
- self.get_user_by_id(id).await?.ok_or_else(|| AppError::Database("Failed to retrieve created user".to_string()))
+ Self::row_to_user,
+ ).map_err(|e| AppError::Database(e.to_string()))
+ }).await
}
pub async fn verify_email_token(&self, token: &str) -> Result<bool, AppError> {