فهرست منبع

Fix connection pool resource initialization and path validation

Fixes two issues in SQLite connection handling:

**Connection Pool Resource Initialization:**
- Move resource creation before incrementing connection counter in pool.rs
- Ensures counter is only incremented after successful resource creation
- Prevents counter increment on resource creation failure
- Fixes potential resource leak where counter could be incremented without a
  valid resource

**Path Validation:**
- Add empty string check before parent directory existence validation
- Allows relative paths like "test.db" to work correctly
- Prevents false negative errors for valid relative database paths
- Only validates parent directory existence for non-empty paths

**Test Coverage:**
- Add test case `bug_opening_relative_path()` to verify relative path handling
- Ensures databases can be created with simple filenames like "test.db"

These changes fix issues where:
1. Connection pool counter could become inconsistent with actual connections
2. Relative database paths were incorrectly rejected
Cesar Rodas 10 ماه پیش
والد
کامیت
b8c5f42390
3فایلهای تغییر یافته به همراه14 افزوده شده و 6 حذف شده
  1. 3 5
      crates/cdk-sql-common/src/pool.rs
  2. 1 1
      crates/cdk-sqlite/src/common.rs
  3. 10 0
      crates/cdk-sqlite/src/mint/mod.rs

+ 3 - 5
crates/cdk-sql-common/src/pool.rs

@@ -208,14 +208,12 @@ where
 
             if self.in_use.load(Ordering::Relaxed) < self.max_size {
                 drop(resources);
-                self.increment_connection_counter();
                 let stale: Arc<AtomicBool> = Arc::new(false.into());
+                let new_resource = RM::new_resource(&self.config, stale.clone(), timeout)?;
+                self.increment_connection_counter();
 
                 return Ok(PooledResource {
-                    resource: Some((
-                        stale.clone(),
-                        RM::new_resource(&self.config, stale, timeout)?,
-                    )),
+                    resource: Some((stale, new_resource)),
                     pool: self.clone(),
                     #[cfg(feature = "prometheus")]
                     start_time: Instant::now(),

+ 1 - 1
crates/cdk-sqlite/src/common.rs

@@ -50,7 +50,7 @@ impl DatabasePool for SqliteConnectionManager {
             // Check if parent directory exists before attempting to open database
             let path_buf = PathBuf::from(path);
             if let Some(parent) = path_buf.parent() {
-                if !parent.exists() {
+                if !parent.to_str().unwrap_or_default().is_empty() && !parent.exists() {
                     return Err(pool::Error::Resource(rusqlite::Error::InvalidPath(
                         path_buf.clone(),
                     )));

+ 10 - 0
crates/cdk-sqlite/src/mint/mod.rs

@@ -32,6 +32,16 @@ mod test {
     mint_db_test!(provide_db);
 
     #[tokio::test]
+    async fn bug_opening_relative_path() {
+        let config: Config = "test.db".into();
+
+        let pool = Pool::<SqliteConnectionManager>::new(config);
+        let db = pool.get();
+        assert!(db.is_ok());
+        let _ = remove_file("test.db");
+    }
+
+    #[tokio::test]
     async fn open_legacy_and_migrate() {
         let file = format!(
             "{}/db.sqlite",