Reels pre-gen: record true media count + real upsert for user_ai_prefs
- pregen_one recorded media_count as planned.len() (beat count); record the actual media item total (media.len(), photos + clips) in both the cache-hit and freshly-rendered ledger paths. Drops the redundant photo_count binding. - Replace upsert_prefs's insert-then-catch-error-then-update dance with a single atomic INSERT ... ON CONFLICT(id) DO UPDATE. Explicit id=1 makes the conflict target deterministic; explicit column .set((...)) keeps None -> NULL overwrite semantics so the row mirrors the latest request exactly, and genuine insert errors surface instead of being swallowed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -84,32 +84,26 @@ impl UserAiPrefsDao for SqliteUserAiPrefsDao {
|
||||
.lock()
|
||||
.expect("Unable to lock UserAiPrefsDao");
|
||||
|
||||
// SQLite: INSERT on first call, UPDATE on subsequent calls.
|
||||
// The first INSERT creates the row with id=1 (auto-increment).
|
||||
// Subsequent calls UPDATE the existing row.
|
||||
let result = diesel::insert_into(dsl::user_ai_prefs)
|
||||
.values(prefs)
|
||||
.execute(connection.deref_mut());
|
||||
|
||||
match result {
|
||||
Ok(_) => {
|
||||
// First insert succeeded.
|
||||
Ok(())
|
||||
}
|
||||
Err(_e) => {
|
||||
// Insert failed (likely due to duplicate key). Update instead.
|
||||
diesel::update(dsl::user_ai_prefs.filter(dsl::id.eq(1)))
|
||||
.set((
|
||||
dsl::voice.eq(&prefs.voice),
|
||||
dsl::tz_offset_minutes.eq(&prefs.tz_offset_minutes),
|
||||
dsl::library.eq(&prefs.library),
|
||||
dsl::updated_at.eq(&prefs.updated_at),
|
||||
))
|
||||
.execute(connection.deref_mut())
|
||||
.map_err(|e| anyhow::anyhow!("Failed to upsert prefs: {}", e))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
// Single-row table (id=1): one atomic upsert. The explicit id=1
|
||||
// makes the conflict target deterministic so the second call
|
||||
// updates in place rather than tripping the CHECK(id=1) constraint,
|
||||
// and real insert errors surface instead of being swallowed into a
|
||||
// separate update branch. The columns are set explicitly (rather
|
||||
// than via AsChangeset) so a None field overwrites to NULL — the
|
||||
// row mirrors the latest request exactly, not a merge of past ones.
|
||||
diesel::insert_into(dsl::user_ai_prefs)
|
||||
.values((dsl::id.eq(1), prefs))
|
||||
.on_conflict(dsl::id)
|
||||
.do_update()
|
||||
.set((
|
||||
dsl::voice.eq(&prefs.voice),
|
||||
dsl::tz_offset_minutes.eq(&prefs.tz_offset_minutes),
|
||||
dsl::library.eq(&prefs.library),
|
||||
dsl::updated_at.eq(&prefs.updated_at),
|
||||
))
|
||||
.execute(connection.deref_mut())
|
||||
.map_err(|e| anyhow::anyhow!("Failed to upsert prefs: {}", e))?;
|
||||
Ok(())
|
||||
})
|
||||
.map_err(|e| DbError::log(DbErrorKind::InsertError, e))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user