@@ -2,70 +2,71 @@ 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: 160_007 } ,
11+ 1700 => % { min_version: "17.3" , min_version_num: 170_003 }
12+ }
813
914 def check_postgres_version do
10- # Start the Repo manually without running migrations
1115 { :ok , _pid } = Repo . start_link ( )
1216
13- # Query the PostgreSQL version
17+ version = get_postgres_version ( )
18+ check_compatibility ( version )
19+
20+ Repo . stop ( )
21+ end
22+
23+ defp get_postgres_version do
1424 { :ok , result } =
1525 SQL . query (
1626 Repo ,
17- "SELECT regexp_replace(version(), 'PostgreSQL ([^ ]+) .*', '\\ 1') AS version" ,
27+ """
28+ SELECT regexp_replace(version(), 'PostgreSQL ([^ ]+) .*', '\\ 1') AS version,
29+ current_setting('server_version_num')::integer AS version_num
30+ """ ,
1831 [ ]
1932 )
2033
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 )
34+ [ version_string , version_num ] = List . first ( result . rows )
2935
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 } ."
36+ # https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQSERVERVERSION
37+ major = div ( version_num , 100 )
3638
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
39+ % Version {
40+ version_string: version_string ,
41+ version_num: version_num ,
42+ major: major
43+ }
44+ end
4945
50- major_int when major_int > 17 ->
46+ defp check_compatibility ( % Version {
47+ major: major ,
48+ version_string: version ,
49+ version_num: version_num
50+ } ) do
51+ cond do
52+ major > 1700 ->
5153 IO . puts (
52- "PostgreSQL version #{ raw_version } is not officially tested or supported yet. Use at your own risk."
54+ "PostgreSQL version #{ version } is not officially tested or supported yet. Use at your own risk."
5355 )
5456
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
57+ not Map . has_key? ( @ version_requirements , major ) ->
58+ supported_versions =
59+ @ version_requirements
60+ |> Map . values ( )
61+ |> Enum . map_join ( " and " , & & 1 . min_version )
5862
59- # Stop the Repo after the check
60- Repo . stop ( )
61- end
63+ raise "PostgreSQL version #{ version } is not supported. Only #{ supported_versions } are supported."
64+
65+ version_num < @ version_requirements [ major ] . min_version_num ->
66+ raise "PostgreSQL version #{ version } is not supported. Minimum required for #{ div ( major , 100 ) } .x is #{ @ version_requirements [ major ] . min_version } ."
6267
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 } "
68+ true ->
69+ IO . puts ( "PostgreSQL version #{ version } is compatible (#{ div ( major , 100 ) } .x series)." )
6970 end
7071 end
7172end
0 commit comments