fix(session): create inventory tables atomically with schema version (#10586)

This commit is contained in:
filip
2026-07-20 14:13:07 -07:00
committed by GitHub
parent 36cb569e36
commit d5a8a3fb90
2 changed files with 5 additions and 59 deletions
+2 -47
View File
@@ -18,7 +18,7 @@ use chrono::{DateTime, Duration, Utc};
use futures::FutureExt;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use sqlx::{Pool, Row, Sqlite, Transaction};
use sqlx::{Row, Sqlite, Transaction};
use std::collections::{BTreeMap, HashMap, HashSet};
use std::panic::AssertUnwindSafe;
use std::sync::{Arc, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard};
@@ -1142,52 +1142,7 @@ fn enriched_model(
}
}
pub async fn create_tables(pool: &Pool<Sqlite>) -> Result<()> {
sqlx::query(
r#"
CREATE TABLE IF NOT EXISTS provider_inventory_entries (
inventory_key TEXT PRIMARY KEY,
provider_id TEXT NOT NULL,
provider_family TEXT NOT NULL,
last_updated_at TEXT,
last_refresh_attempt_at TEXT,
last_refresh_error TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
"#,
)
.execute(pool)
.await?;
sqlx::query(
r#"
CREATE TABLE IF NOT EXISTS provider_inventory_models (
inventory_key TEXT NOT NULL REFERENCES provider_inventory_entries(inventory_key) ON DELETE CASCADE,
ordinal INTEGER NOT NULL,
model_id TEXT NOT NULL,
name TEXT NOT NULL,
family TEXT,
context_limit INTEGER,
reasoning BOOLEAN,
recommended BOOLEAN,
PRIMARY KEY (inventory_key, ordinal)
)
"#,
)
.execute(pool)
.await?;
sqlx::query(
"CREATE INDEX IF NOT EXISTS idx_provider_inventory_provider_id ON provider_inventory_entries(provider_id)",
)
.execute(pool)
.await?;
Ok(())
}
pub async fn create_tables_in_tx(tx: &mut Transaction<'_, Sqlite>) -> Result<()> {
pub async fn create_tables(tx: &mut Transaction<'_, Sqlite>) -> Result<()> {
sqlx::query(
r#"
CREATE TABLE IF NOT EXISTS provider_inventory_entries (
+3 -12
View File
@@ -891,12 +891,6 @@ impl SessionStorage {
Ok(&self.pool)
}
pub async fn create(session_dir: &Path) -> Result<Self> {
let storage = Self::new(session_dir.to_path_buf());
Self::create_schema(&storage.pool).await?;
Ok(storage)
}
async fn create_schema(pool: &Pool<Sqlite>) -> Result<()> {
// Run schema creation under `BEGIN IMMEDIATE` so SQLite serializes
// writers across processes. Combined with `IF NOT EXISTS` on every
@@ -1031,12 +1025,9 @@ impl SessionStorage {
.execute(&mut *tx)
.await?;
tx.commit().await?;
crate::providers::inventory::create_tables(&mut tx).await?;
// The inventory tables already use `CREATE TABLE IF NOT EXISTS`
// and run on the shared pool, so they don't need to be inside
// the same transaction.
crate::providers::inventory::create_tables(pool).await?;
tx.commit().await?;
Ok(())
}
@@ -1390,7 +1381,7 @@ impl SessionStorage {
.await?;
}
11 => {
crate::providers::inventory::create_tables_in_tx(tx).await?;
crate::providers::inventory::create_tables(tx).await?;
}
12 => {
// Add archived_at, project_id columns to sessions.