Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit fb3ac37

Browse filesBrowse files
Merge pull request theseus-rs#162 from jsdt/jsdt/reuse-children
Check for existing installations in children before installing.
2 parents 3dd9541 + 4746b48 commit fb3ac37
Copy full SHA for fb3ac37

File tree

Expand file treeCollapse file tree

1 file changed

+52
-11
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+52
-11
lines changed

‎postgresql_embedded/src/postgresql.rs

Copy file name to clipboardExpand all lines: postgresql_embedded/src/postgresql.rs
+52-11Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ use postgresql_commands::initdb::InitDbBuilder;
1313
use postgresql_commands::pg_ctl::Mode::{Start, Stop};
1414
use postgresql_commands::pg_ctl::PgCtlBuilder;
1515
use postgresql_commands::pg_ctl::ShutdownMode::Fast;
16+
use semver::Version;
1617
use sqlx::{PgPool, Row};
17-
use std::fs::{remove_dir_all, remove_file};
18+
use std::fs::{read_dir, remove_dir_all, remove_file};
1819
use std::io::prelude::*;
1920
use std::net::TcpListener;
21+
use std::path::PathBuf;
2022
use tracing::{debug, instrument};
2123

2224
use crate::Error::{CreateDatabaseError, DatabaseExistsError, DropDatabaseError};
@@ -73,7 +75,7 @@ impl PostgreSQL {
7375
Status::Started
7476
} else if self.is_initialized() {
7577
Status::Stopped
76-
} else if self.is_installed() {
78+
} else if self.installed_dir().is_some() {
7779
Status::Installed
7880
} else {
7981
Status::NotInstalled
@@ -86,13 +88,48 @@ impl PostgreSQL {
8688
&self.settings
8789
}
8890

89-
/// Check if the `PostgreSQL` server is installed
90-
fn is_installed(&self) -> bool {
91-
let Some(version) = self.settings.version.exact_version() else {
92-
return false;
93-
};
91+
/// Find a directory where `PostgreSQL` server is installed.
92+
/// This first checks if the installation directory exists and matches the version requirement.
93+
/// If it doesn't, it will search all the child directories for the latest version that matches the requirement.
94+
/// If it returns None, we couldn't find a matching installation.
95+
fn installed_dir(&self) -> Option<PathBuf> {
9496
let path = &self.settings.installation_dir;
95-
path.ends_with(version.to_string()) && path.exists()
97+
let maybe_path_version = path
98+
.file_name()
99+
.and_then(|file_name| Version::parse(&file_name.to_string_lossy()).ok());
100+
// If this directory matches the version requirement, we're done.
101+
if let Some(path_version) = maybe_path_version {
102+
if self.settings.version.matches(&path_version) && path.exists() {
103+
return Some(path.clone());
104+
}
105+
}
106+
107+
// Get all directories in the path as versions.
108+
let mut versions = read_dir(path)
109+
.ok()?
110+
.filter_map(|entry| {
111+
let Some(entry) = entry.ok() else {
112+
// We ignore filesystem errors.
113+
return None;
114+
};
115+
// Skip non-directories
116+
if !entry.file_type().ok()?.is_dir() {
117+
return None;
118+
}
119+
let file_name = entry.file_name();
120+
let version = Version::parse(&file_name.to_string_lossy()).ok()?;
121+
if self.settings.version.matches(&version) {
122+
Some((version, entry.path()))
123+
} else {
124+
None
125+
}
126+
})
127+
.collect::<Vec<_>>();
128+
// Sort the versions in descending order i.e. latest version first
129+
versions.sort_by(|(a, _), (b, _)| b.cmp(a));
130+
// Get the first matching version as the best match
131+
let version_path = versions.first().map(|(_, path)| path.clone());
132+
version_path
96133
}
97134

98135
/// Check if the `PostgreSQL` server is initialized
@@ -111,10 +148,14 @@ impl PostgreSQL {
111148
/// If the data directory already exists, the database will not be initialized.
112149
#[instrument(skip(self))]
113150
pub async fn setup(&mut self) -> Result<()> {
114-
if !self.is_installed() {
115-
self.install().await?;
151+
match self.installed_dir() {
152+
Some(installed_dir) => {
153+
self.settings.installation_dir = installed_dir;
154+
}
155+
None => {
156+
self.install().await?;
157+
}
116158
}
117-
118159
if !self.is_initialized() {
119160
self.initialize().await?;
120161
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.