Skip to content

Commit 99871ef

Browse files
committed
rewrite to rely on server_version_num
1 parent 85b45f2 commit 99871ef

2 files changed

Lines changed: 44 additions & 46 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
- feat: use Grafana 12.0.2 (#4805 - @swiffer)
1717
- feat(mqtt): always publish healthy status and disable retain to prevent stale healthy status via mqtt (#4817 - @allivshits)
1818
- feat: use the k8s-style API introduced in Grafana v12 if using manual dashboard setup (#4764- @IngmarStein)
19+
- feat(db-check): allow beta / rc PostgreSQL versions for testing (#4795 - @swiffer)
1920

2021
#### Build, CI, internal
2122

lib/teslamate/database_check.ex

Lines changed: 43 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,70 +2,67 @@ 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{major: major, version_string: version, version_num: version_num}) do
47+
cond do
48+
major > 1700 ->
5149
IO.puts(
52-
"PostgreSQL version #{raw_version} is not officially tested or supported yet. Use at your own risk."
50+
"PostgreSQL version #{version} is not officially tested or supported yet. Use at your own risk."
5351
)
5452

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
53+
not Map.has_key?(@version_requirements, major) ->
54+
supported_versions =
55+
@version_requirements
56+
|> Map.values()
57+
|> Enum.map_join(" and ", & &1.min_version)
5858

59-
# Stop the Repo after the check
60-
Repo.stop()
61-
end
59+
raise "PostgreSQL version #{version} is not supported. Only #{supported_versions} are supported."
60+
61+
version_num < @version_requirements[major].min_version_num ->
62+
raise "PostgreSQL version #{version} is not supported. Minimum required for #{div(major, 100)}.x is #{@version_requirements[major].min_version}."
6263

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}"
64+
true ->
65+
IO.puts("PostgreSQL version #{version} is compatible (#{div(major, 100)}.x series).")
6966
end
7067
end
7168
end

0 commit comments

Comments
 (0)