mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-25 14:53:34 +00:00
fix(setup): validate PostgreSQL version and pgvector availability before migrations (#423)
* fix(setup): validate PostgreSQL version and pgvector before migrations The setup wizard accepted any DATABASE_URL without checking the server version or pgvector availability. Users who installed PostgreSQL 14 (or any version < 15) got opaque migration failures. Users without pgvector installed hit CREATE EXTENSION errors at runtime. After a successful connection, the wizard now: 1. Queries SHOW server_version and rejects versions below 15 2. Checks pg_available_extensions for the vector extension Both checks provide actionable error messages with platform-specific install guidance. Closes #415 Closes #416 Co-Authored-By: Claude Opus 4.6 <[email protected]> * refactor: extract version constant, fix hex escapes in pgvector message - Extract MIN_PG_MAJOR_VERSION constant to avoid magic number - Replace \x20 hex escapes with regular spaces in install guidance Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix(setup): use detected PG version in pgvector install instructions The pgvector install hints were hardcoded for PG 16. Since we already parse major_version from SHOW server_version, use it dynamically so users on PG 15 or 17 get correct package names. Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: Claude Opus 4.6 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
c6bfd18401
commit
e794f39726
+51
-1
@@ -543,6 +543,10 @@ impl SetupWizard {
|
||||
}
|
||||
|
||||
/// Test PostgreSQL connection and store the pool.
|
||||
///
|
||||
/// After connecting, validates:
|
||||
/// 1. PostgreSQL version >= 15 (required for pgvector compatibility)
|
||||
/// 2. pgvector extension is available (required for embeddings/vector search)
|
||||
#[cfg(feature = "postgres")]
|
||||
async fn test_database_connection_postgres(&mut self, url: &str) -> Result<(), SetupError> {
|
||||
let mut cfg = PoolConfig::new();
|
||||
@@ -556,11 +560,57 @@ impl SetupWizard {
|
||||
.create_pool(Some(Runtime::Tokio1), NoTls)
|
||||
.map_err(|e| SetupError::Database(format!("Failed to create pool: {}", e)))?;
|
||||
|
||||
let _ = pool
|
||||
let client = pool
|
||||
.get()
|
||||
.await
|
||||
.map_err(|e| SetupError::Database(format!("Failed to connect: {}", e)))?;
|
||||
|
||||
// Check PostgreSQL server version (need 15+ for pgvector)
|
||||
let version_row = client
|
||||
.query_one("SHOW server_version", &[])
|
||||
.await
|
||||
.map_err(|e| SetupError::Database(format!("Failed to query server version: {}", e)))?;
|
||||
let version_str: &str = version_row.get(0);
|
||||
let major_version = version_str
|
||||
.split('.')
|
||||
.next()
|
||||
.and_then(|v| v.parse::<u32>().ok())
|
||||
.unwrap_or(0);
|
||||
|
||||
const MIN_PG_MAJOR_VERSION: u32 = 15;
|
||||
|
||||
if major_version < MIN_PG_MAJOR_VERSION {
|
||||
return Err(SetupError::Database(format!(
|
||||
"PostgreSQL {} detected. IronClaw requires PostgreSQL {} or later for pgvector support.\n\
|
||||
Upgrade: https://www.postgresql.org/download/",
|
||||
version_str, MIN_PG_MAJOR_VERSION
|
||||
)));
|
||||
}
|
||||
|
||||
// Check if pgvector extension is available
|
||||
let pgvector_row = client
|
||||
.query_opt(
|
||||
"SELECT 1 FROM pg_available_extensions WHERE name = 'vector'",
|
||||
&[],
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
SetupError::Database(format!("Failed to check pgvector availability: {}", e))
|
||||
})?;
|
||||
|
||||
if pgvector_row.is_none() {
|
||||
return Err(SetupError::Database(format!(
|
||||
"pgvector extension not found on your PostgreSQL server.\n\n\
|
||||
Install it:\n \
|
||||
macOS: brew install pgvector\n \
|
||||
Ubuntu: apt install postgresql-{0}-pgvector\n \
|
||||
Docker: use the pgvector/pgvector:pg{0} image\n \
|
||||
Source: https://github.com/pgvector/pgvector#installation\n\n\
|
||||
Then restart PostgreSQL and re-run: ironclaw onboard",
|
||||
major_version
|
||||
)));
|
||||
}
|
||||
|
||||
self.db_pool = Some(pool);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user