Skip to content

Commit 9319d71

Browse files
authored
Merge pull request #153 from supabase/add_default_version
add support for `default_version` in control file
2 parents e4402ff + 1ef85d5 commit 9319d71

File tree

4 files changed

+460
-0
lines changed

4 files changed

+460
-0
lines changed

cli/src/client.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ pub struct PublishPackageRequest<'a> {
165165
pub package_description: &'a Option<String>,
166166
pub relocatable: bool,
167167
pub requires: &'a [String],
168+
pub default_version: &'a str,
168169
}
169170

170171
#[derive(Serialize)]

cli/src/commands/publish.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::collections::HashSet;
12
use std::path::Path;
23

34
use crate::client::{
@@ -21,7 +22,14 @@ pub async fn publish(
2122
return Err(anyhow::anyhow!("No `README.md` file found"));
2223
};
2324

25+
let valid_versions = get_valid_versions(&payload);
2426
let request = create_publish_package_request(&payload);
27+
if !valid_versions.contains(request.default_version) {
28+
return Err(anyhow::anyhow!(
29+
"default_version in control file should be set to one of the following: {}",
30+
valid_versions.into_iter().collect::<Vec<&str>>().join(", ")
31+
));
32+
}
2533
client.publish_package(&jwt, &request).await?;
2634

2735
if payload.install_files.is_empty() {
@@ -78,6 +86,7 @@ fn create_publish_package_request(payload: &Payload) -> PublishPackageRequest {
7886
package_description: &payload.metadata.comment,
7987
relocatable: payload.metadata.relocatable,
8088
requires: &payload.metadata.requires,
89+
default_version: &payload.metadata.default_version,
8190
}
8291
}
8392

@@ -105,3 +114,18 @@ fn create_publich_package_upgrade_request<'a>(
105114
upgrade_source: &upgrade_file.body,
106115
}
107116
}
117+
118+
fn get_valid_versions(payload: &Payload) -> HashSet<&str> {
119+
let mut valid_versions: HashSet<&str> = HashSet::new();
120+
121+
for install_file in &payload.install_files {
122+
valid_versions.insert(&install_file.version);
123+
}
124+
125+
for upgrade_file in &payload.upgrade_files {
126+
valid_versions.insert(&upgrade_file.from_version);
127+
valid_versions.insert(&upgrade_file.to_version);
128+
}
129+
130+
valid_versions
131+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
-- default_version column has a default value '0.0.0' only temporarily because the column is not null.
2+
-- It will be removed below.
3+
alter table app.packages
4+
add column default_version_struct app.semver not null default app.text_to_semver('0.0.0'),
5+
add column default_version text generated always as (app.semver_to_text(default_version_struct)) stored;
6+
7+
-- for now we set the default version to current latest version
8+
-- new client will allow users to set a specific default version in the control file
9+
update app.packages
10+
set default_version_struct = app.text_to_semver(pp.latest_version)
11+
from public.packages pp
12+
where packages.id = pp.id;
13+
14+
-- now that every row has a valid default_version, remove the default value of '0.0.0'
15+
alter table app.packages
16+
alter column default_version_struct drop default;
17+
18+
-- add new default_version column to the view
19+
create or replace view public.packages as
20+
select
21+
pa.id,
22+
pa.package_name,
23+
pa.handle,
24+
pa.partial_name,
25+
newest_ver.version as latest_version,
26+
newest_ver.description_md,
27+
pa.control_description,
28+
pa.control_requires,
29+
pa.created_at,
30+
pa.default_version
31+
from
32+
app.packages pa,
33+
lateral (
34+
select *
35+
from app.package_versions pv
36+
where pv.package_id = pa.id
37+
order by pv.version_struct desc
38+
limit 1
39+
) newest_ver;
40+
41+
-- grant insert and update permissions to authenticated users on the new default_version_struct column
42+
grant insert (partial_name, handle, control_description, control_relocatable, control_requires, default_version_struct)
43+
on app.packages
44+
to authenticated;
45+
46+
grant update (control_description, control_relocatable, control_requires, default_version_struct)
47+
on app.packages
48+
to authenticated;
49+
50+
-- publish_package accepts an additional `default_version` argument
51+
drop function public.publish_package(app.valid_name, varchar, bool, text[]);
52+
create or replace function public.publish_package(
53+
package_name app.valid_name,
54+
package_description varchar(1000),
55+
relocatable bool default false,
56+
requires text[] default '{}',
57+
default_version text default null
58+
)
59+
returns void
60+
language plpgsql
61+
as $$
62+
declare
63+
account app.accounts = account from app.accounts account where id = auth.uid();
64+
require text;
65+
begin
66+
if account.handle is null then
67+
raise exception 'user not logged in';
68+
end if;
69+
70+
if default_version is null then
71+
raise exception 'default_version is required. If you are on `dbdev` CLI version 0.1.5 or older upgrade to the latest version.';
72+
end if;
73+
74+
foreach require in array requires
75+
loop
76+
if not exists (
77+
select true
78+
from app.allowed_extensions
79+
where
80+
name = require
81+
) then
82+
raise exception '`requires` in the control file can''t have `%` in it', require;
83+
end if;
84+
end loop;
85+
86+
insert into app.packages(handle, partial_name, control_description, control_relocatable, control_requires, default_version_struct)
87+
values (account.handle, package_name, package_description, relocatable, requires, app.text_to_semver(default_version))
88+
on conflict on constraint packages_handle_partial_name_key
89+
do update
90+
set control_description = excluded.control_description,
91+
control_relocatable = excluded.control_relocatable,
92+
control_requires = excluded.control_requires,
93+
default_version_struct = excluded.default_version_struct;
94+
end;
95+
$$;

0 commit comments

Comments
 (0)