|
1 |
| --- Enter migration here |
2 |
| - |
3 | 1 | /*
|
4 |
| -example of a table that could be created after setup complete |
5 |
| -
|
6 |
| -- uncomment the statements below |
7 |
| -- save the file and graphile-migrate will update the schema into database automagically |
8 |
| -- any "drop" statements should be at the top (in reverse order) |
9 |
| -reverse order as we could have references |
10 |
| -from the second created table to the first created table |
11 |
| -
|
12 |
| -here is an pseudo example: |
13 |
| -DROP C; |
14 |
| -DROP B; |
15 |
| -DROP A; |
16 |
| -CREATE A; |
17 |
| -CREATE B; |
18 |
| -CREATE C; |
19 |
| -
|
20 |
| -if references exists from B -> A |
21 |
| -we have to DROP B before DROP A we have references that point to A from B |
22 |
| -
|
23 |
| -In the example below post and feed need to be |
24 |
| -deleted in reverse order due to feed -> post |
| 2 | +
|
| 3 | +This project is using Graphile Migrate to manage migrations; please be aware |
| 4 | +the Graphile Migrate works in a different way to most other migration |
| 5 | +frameworks: |
| 6 | +
|
| 7 | +- it's "up-only" (there are no down migrations) |
| 8 | +- the current migration (this file) is executed every time it is saved |
| 9 | +- it requires *significant discipline* as changes made in this file will |
| 10 | + persist locally even after they are deleted from the file |
| 11 | +
|
| 12 | +Because during development the current migration is expected to run multiple |
| 13 | +times, the migration has to deal with both the situation where it _has_ been |
| 14 | +executed before, and where it _hasn't_ been executed before. |
| 15 | +
|
| 16 | +You can (and should) read more on Graphile Migrate in its repository: |
| 17 | +
|
| 18 | + https://github.com/graphile/migrate |
| 19 | +
|
| 20 | +You can absolutely switch out Graphile Migrate for a more traditional |
| 21 | +migration framework if you prefer. |
| 22 | +
|
25 | 23 | */
|
26 | 24 |
|
27 |
| --- UNCOMMENT FROM HERE -- |
| 25 | +-------------------------------------------------------------------------------- |
| 26 | + |
| 27 | +/* |
| 28 | +
|
| 29 | +What follows is an example of a table that could be created after setup is |
| 30 | +complete. To use it uncomment the statements below and save the file - |
| 31 | +graphile-migrate will update the schema into database automagically and |
| 32 | +PostGraphile should automatically detect these changes and reflect them |
| 33 | +through GraphQL which you should see immediately in GraphiQL. |
28 | 34 |
|
29 |
| --- drop table if exists app_public.feed; |
30 |
| --- drop table if exists app_public.post; |
| 35 | +Note any "DROP" statements should be at the top in reverse order of creation. |
| 36 | +The reason for reverse order is because we could have references from the |
| 37 | +second created resource to the first created resource. So your migration |
| 38 | +might look something like this pseudo-example: |
31 | 39 |
|
32 |
| --- drop type if exists app_public.post_topic; |
| 40 | + DROP C; |
| 41 | + DROP B; |
| 42 | + DROP A; |
| 43 | + CREATE A; |
| 44 | + CREATE B REFERENCING A; |
| 45 | + CREATE C REFERENCING A; |
33 | 46 |
|
34 |
| --- create type app_public.post_topic as enum ( |
35 |
| --- 'discussion', |
36 |
| --- 'inspiration', |
37 |
| --- 'help', |
38 |
| --- 'showcase' |
| 47 | +We have to DROP B before DROP A because we have references that point to A |
| 48 | +from B. |
| 49 | +
|
| 50 | +You can uncomment the following lines one block a time and safe the file to view |
| 51 | +the changes. |
| 52 | +
|
| 53 | +**IMPORTANT**: when you uncomment the `CREATE TABLE` statements this will not |
| 54 | +result in the table being added to the GraphQL API, this is because we are |
| 55 | +using `ignoreRBAC: false` so we do not expose tables until you `GRANT` the |
| 56 | +relevant operations on them. The tables will appear when you uncomment the |
| 57 | +`GRANT` lines. |
| 58 | +
|
| 59 | +*/ |
| 60 | + |
| 61 | +-- drop table if exists app_public.user_feed_posts; |
| 62 | +-- drop table if exists app_public.posts; |
| 63 | +-- drop table if exists app_public.topics; |
| 64 | + |
| 65 | +-- create table app_public.topics ( |
| 66 | +-- title text not null primary key |
39 | 67 | -- );
|
| 68 | +-- alter table app_public.topics enable row level security; |
40 | 69 |
|
41 |
| --- create table app_public.post ( |
| 70 | +-- create table app_public.posts ( |
42 | 71 | -- id serial primary key,
|
43 |
| --- author_id integer not null references app_public.users(id), |
| 72 | +-- author_id int default app_public.current_user_id() references app_public.users(id) on delete set null, |
44 | 73 | -- headline text not null check (char_length(headline) < 280),
|
45 | 74 | -- body text,
|
46 |
| --- topic app_public.post_topic, |
47 |
| --- created_at timestamp default now() |
| 75 | +-- topic text not null references app_public.topics on delete restrict, |
| 76 | +-- created_at timestamptz not null default now(), |
| 77 | +-- updated_at timestamptz not null default now() |
48 | 78 | -- );
|
| 79 | +-- alter table app_public.posts enable row level security; |
49 | 80 |
|
50 |
| --- comment on table app_public.post is 'a forum post written by a user.'; |
51 |
| --- comment on column app_public.post.id is 'the primary key for the post.'; |
52 |
| --- comment on column app_public.post.headline is 'the title written by the user.'; |
53 |
| --- comment on column app_public.post.author_id is 'the id of the author user.'; |
54 |
| --- comment on column app_public.post.topic is 'the topic this has been posted in.'; |
55 |
| --- comment on column app_public.post.body is 'the main body text of our post.'; |
56 |
| --- comment on column app_public.post.created_at is 'the time this post was created.'; |
| 81 | +-- create trigger _100_timestamps before insert or update on app_public.posts for each row execute procedure app_private.tg__timestamps(); |
57 | 82 |
|
58 |
| --- create table app_public.feed ( |
| 83 | +-- grant |
| 84 | +-- select, |
| 85 | +-- insert (headline, body, topic), |
| 86 | +-- update (headline, body, topic), |
| 87 | +-- delete |
| 88 | +-- on app_public.posts to :DATABASE_VISITOR; |
| 89 | + |
| 90 | +-- create policy select_all on app_public.posts for select using (true); |
| 91 | +-- create policy manage_own on app_public.posts for all using (author_id = app_public.current_user_id()); |
| 92 | +-- create policy manage_as_admin on app_public.posts for all using (exists (select 1 from app_public.users where is_admin is true and id = app_public.current_user_id())); |
| 93 | + |
| 94 | +-- comment on table app_public.posts is 'A forum post written by a `User`.'; |
| 95 | +-- comment on column app_public.posts.id is 'The primary key for the `Post`.'; |
| 96 | +-- comment on column app_public.posts.headline is 'The title written by the `User`.'; |
| 97 | +-- comment on column app_public.posts.author_id is 'The id of the author `User`.'; |
| 98 | +-- comment on column app_public.posts.topic is 'The `Topic` this has been posted in.'; |
| 99 | +-- comment on column app_public.posts.body is 'The main body text of our `Post`.'; |
| 100 | +-- comment on column app_public.posts.created_at is 'The time this `Post` was created.'; |
| 101 | +-- comment on column app_public.posts.updated_at is 'The time this `Post` was last modified (or created).'; |
| 102 | + |
| 103 | +-- create table app_public.user_feed_posts ( |
59 | 104 | -- id serial primary key,
|
60 |
| --- posts integer not null references app_public.post(id), |
61 |
| --- created_at timestamp default now() |
| 105 | +-- user_id int not null references app_public.users on delete cascade, |
| 106 | +-- post_id int not null references app_public.posts on delete cascade, |
| 107 | +-- created_at timestamptz not null default now() |
62 | 108 | -- );
|
| 109 | +-- alter table app_public.user_feed_posts enable row level security; |
| 110 | + |
| 111 | +-- grant select on app_public.user_feed_posts to :DATABASE_VISITOR; |
| 112 | + |
| 113 | +-- create policy select_own on app_public.user_feed_posts for select using (user_id = app_public.current_user_id()); |
63 | 114 |
|
64 |
| --- comment on table app_public.feed is 'the feed of the posts'; |
65 |
| --- comment on column app_public.feed.id is 'the primary key for the feed.'; |
66 |
| --- comment on column app_public.feed.created_at is 'the time this feed was created.'; |
| 115 | +-- comment on table app_public.user_feed_posts is 'A feed of `Post`s relevant to a particular `User`.'; |
| 116 | +-- comment on column app_public.user_feed_posts.id is 'An identifier for this entry in the feed.'; |
| 117 | +-- comment on column app_public.user_feed_posts.created_at is 'The time this feed item was added.'; |
0 commit comments