@@ -2,70 +2,60 @@ defmodule TeslaMate.DatabaseCheck do
22 alias Ecto.Adapters.SQL
33 alias TeslaMate.Repo
44
5- # Minimum versions for supported major releases
6- @ min_version_16 "16.7"
7- @ min_version_17 "17.3"
5+ defmodule Version do
6+ defstruct [ :version_string , :version_num , :major ]
7+ end
8+
9+ @ version_requirements % {
10+ 1600 => % { min_version: "16.7" , min_version_num: 160007 } ,
11+ 1700 => % { min_version: "17.3" , min_version_num: 170003 }
12+ }
813
914 def check_postgres_version do
10- # Start the Repo manually without running migrations
1115 { :ok , _pid } = Repo . start_link ( )
16+ version = get_postgres_version ( )
17+ check_compatibility ( version )
18+ Repo . stop ( )
19+ end
1220
13- # Query the PostgreSQL version
21+ defp get_postgres_version do
1422 { :ok , result } =
1523 SQL . query (
1624 Repo ,
17- "SELECT regexp_replace(version(), 'PostgreSQL ([^ ]+) .*', '\\ 1') AS version" ,
25+ "SELECT
26+ regexp_replace(version(), 'PostgreSQL ([^ ]+) .*', '\\ 1') AS version,
27+ current_setting('server_version_num')::integer AS version_num" ,
1828 [ ]
1929 )
2030
21- raw_version = result . rows |> List . first ( ) |> List . first ( )
22-
23- # Normalize to SemVer by appending .0 if needed
24- version = normalize_version ( raw_version )
25-
26- # Split into major and minor parts
27- [ major , _minor ] = String . split ( version , "." , parts: 2 )
28- major_int = String . to_integer ( major )
31+ [ version_string , version_num ] = List . first ( result . rows )
2932
30- # Check based on major version
31- case major_int do
32- 16 ->
33- case Version . compare ( version , normalize_version ( @ min_version_16 ) ) do
34- :lt ->
35- raise "PostgreSQL version #{ raw_version } is not supported. Minimum required for 16.x is #{ @ min_version_16 } ."
33+ # https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQSERVERVERSION
34+ major = div ( version_num , 100 )
3635
37- _ ->
38- IO . puts ( "PostgreSQL version #{ raw_version } is compatible (16.x series)." )
39- end
40-
41- 17 ->
42- case Version . compare ( version , normalize_version ( @ min_version_17 ) ) do
43- :lt ->
44- raise "PostgreSQL version #{ raw_version } is not supported. Minimum required for 17.x is #{ @ min_version_17 } ."
45-
46- _ ->
47- IO . puts ( "PostgreSQL version #{ raw_version } is compatible (17.x series)." )
48- end
36+ % Version {
37+ version_string: version_string ,
38+ version_num: version_num ,
39+ major: major ,
40+ }
41+ end
4942
50- major_int when major_int > 17 ->
51- IO . puts (
52- "PostgreSQL version #{ raw_version } is not officially tested or supported yet. Use at your own risk."
53- )
43+ defp check_compatibility ( % Version { major: major , version_string: version , version_num: version_num } ) do
44+ cond do
45+ major > 1700 ->
46+ IO . puts ( "PostgreSQL version #{ version } is not officially tested or supported yet. Use at your own risk." )
5447
55- _ ->
56- raise "PostgreSQL version #{ raw_version } is not supported. Only 16.x (min #{ @ min_version_16 } ) and 17.x (min #{ @ min_version_17 } ) are supported."
57- end
48+ not Map . has_key? ( @ version_requirements , major ) ->
49+ supported_versions = @ version_requirements
50+ |> Map . values ( )
51+ |> Enum . map_join ( " and " , & ( & 1 . min_version ) )
52+ raise "PostgreSQL version #{ version } is not supported. Only #{ supported_versions } are supported."
5853
59- # Stop the Repo after the check
60- Repo . stop ( )
61- end
54+ version_num < @ version_requirements [ major ] . min_version_num ->
55+ raise "PostgreSQL version #{ version } is not supported. Minimum required for #{ div ( major , 100 ) } .x is #{ @ version_requirements [ major ] . min_version } ."
6256
63- # Helper function to normalize PostgreSQL version to SemVer
64- defp normalize_version ( version ) do
65- case String . split ( version , "." ) do
66- [ major , minor ] -> "#{ major } .#{ minor } .0"
67- [ major , minor , patch | _ ] -> "#{ major } .#{ minor } .#{ patch } "
68- _ -> raise "Invalid PostgreSQL version format: #{ version } "
57+ true ->
58+ IO . puts ( "PostgreSQL version #{ version } is compatible (#{ div ( major , 100 ) } .x series)." )
6959 end
7060 end
7161end
0 commit comments