@@ -15,13 +15,11 @@ use postgresql_commands::CommandBuilder;
15
15
use postgresql_commands:: CommandExecutor ;
16
16
use semver:: Version ;
17
17
use sqlx:: { PgPool , Row } ;
18
- use std:: ffi:: OsStr ;
19
- use std:: fs:: { remove_dir_all, remove_file} ;
18
+ use std:: fs:: { read_dir, remove_dir_all, remove_file} ;
20
19
use std:: io:: prelude:: * ;
21
20
use std:: net:: TcpListener ;
22
21
use std:: path:: PathBuf ;
23
22
use tracing:: { debug, instrument} ;
24
- use walkdir:: WalkDir ;
25
23
26
24
use crate :: Error :: { CreateDatabaseError , DatabaseExistsError , DropDatabaseError } ;
27
25
@@ -95,48 +93,43 @@ impl PostgreSQL {
95
93
/// If it doesn't, it will search all the child directories for the latest version that matches the requirement.
96
94
/// If it returns None, we couldn't find a matching installation.
97
95
fn installed_dir ( & self ) -> Option < PathBuf > {
98
- fn file_name_to_version ( name : & OsStr ) -> Option < Version > {
99
- Version :: parse ( name. to_string_lossy ( ) . as_ref ( ) ) . ok ( )
100
- }
101
96
let path = & self . settings . installation_dir ;
102
97
let maybe_path_version = path
103
98
. file_name ( )
104
- . map ( |name| file_name_to_version ( name) )
105
- . flatten ( ) ;
99
+ . and_then ( |file_name| Version :: parse ( & file_name. to_string_lossy ( ) ) . ok ( ) ) ;
106
100
// If this directory matches the version requirement, we're done.
107
101
if let Some ( path_version) = maybe_path_version {
108
102
if self . settings . version . matches ( & path_version) && path. exists ( ) {
109
- return Some ( path. to_path_buf ( ) ) ;
110
- }
111
- }
112
- // Otherwise we check the child directories.
113
- let mut max_version: Option < Version > = None ;
114
- let mut max_path: Option < PathBuf > = None ;
115
- for entry in WalkDir :: new ( path) . min_depth ( 1 ) . max_depth ( 1 ) {
116
- let Some ( entry) = entry. ok ( ) else {
117
- // We ignore filesystem errors.
118
- continue ;
119
- } ;
120
- // Skip non-directories
121
- if !entry. file_type ( ) . is_dir ( ) {
122
- continue ;
103
+ return Some ( path. clone ( ) ) ;
123
104
}
124
- // If it doesn't look like a version, we ignore it.
125
- let Some ( version) = file_name_to_version ( entry. file_name ( ) ) else {
126
- continue ;
127
- } ;
128
- // If it doesn't match the version requirement, we ignore it.
129
- if !self . settings . version . matches ( & version) {
130
- continue ;
131
- }
132
- // If we already found a version that's greater or equal, we ignore it.
133
- if max_version. iter ( ) . any ( |prev_max| * prev_max >= version) {
134
- continue ;
135
- }
136
- max_version = Some ( version. clone ( ) ) ;
137
- max_path = Some ( entry. path ( ) . to_path_buf ( ) ) ;
138
105
}
139
- max_path
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
140
133
}
141
134
142
135
/// Check if the `PostgreSQL` server is initialized
0 commit comments