Adding User and Community types.
This commit is contained in:
parent
92ea945619
commit
a62a7cb6a2
18 changed files with 597 additions and 121 deletions
62
API.md
62
API.md
|
@ -49,7 +49,13 @@
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"type": "Person",
|
"type": "Person",
|
||||||
"id": "https://rust-reddit-fediverse/api/v1/user/sally_smith",
|
"id": "https://rust-reddit-fediverse/api/v1/user/sally_smith",
|
||||||
"name": "sally_smith", // TODO can't find an activitypub vocab for alias.
|
"inbox": "https://rust-reddit-fediverse/api/v1/user/sally_smith/inbox",
|
||||||
|
"outbox": "https://rust-reddit-fediverse/api/v1/user/sally_smith/outbox",
|
||||||
|
"liked": "https://rust-reddit-fediverse/api/v1/user/sally_smith/liked",
|
||||||
|
"disliked": "https://rust-reddit-fediverse/api/v1/user/sally_smith/disliked",
|
||||||
|
"following": "https://rust-reddit-fediverse/api/v1/user/sally_smith/following",
|
||||||
|
"name": "sally_smith",
|
||||||
|
"preferredUsername": "Sally",
|
||||||
"icon"?: {
|
"icon"?: {
|
||||||
"type": "Image",
|
"type": "Image",
|
||||||
"name": "User icon",
|
"name": "User icon",
|
||||||
|
@ -63,7 +69,6 @@
|
||||||
```
|
```
|
||||||
|
|
||||||
### [Community / Group](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-group)
|
### [Community / Group](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-group)
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
@ -73,6 +78,7 @@
|
||||||
"attributedTo": [ // The moderators
|
"attributedTo": [ // The moderators
|
||||||
"http://joe.example.org",
|
"http://joe.example.org",
|
||||||
],
|
],
|
||||||
|
"followers": "https://rust-reddit-fediverse/api/v1/community/today_i_learned/followers",
|
||||||
"startTime": "2014-12-31T23:00:00-08:00",
|
"startTime": "2014-12-31T23:00:00-08:00",
|
||||||
"summary"?: "The group's tagline",
|
"summary"?: "The group's tagline",
|
||||||
"attachment: [{}] // TBD, these would be where strong types for custom styles, and images would work.
|
"attachment: [{}] // TBD, these would be where strong types for custom styles, and images would work.
|
||||||
|
@ -91,16 +97,13 @@
|
||||||
"url": "https://news.blah.com"
|
"url": "https://news.blah.com"
|
||||||
"attributedTo": "http://joe.example.org", // The poster
|
"attributedTo": "http://joe.example.org", // The poster
|
||||||
"startTime": "2014-12-31T23:00:00-08:00",
|
"startTime": "2014-12-31T23:00:00-08:00",
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### [Post Listings / Ordered CollectionPage](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-orderedcollectionpage)
|
### [Post Listings / Ordered CollectionPage](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-orderedcollectionpage)
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Page 1 of Sally's front page",
|
|
||||||
"type": "OrderedCollectionPage",
|
"type": "OrderedCollectionPage",
|
||||||
"id": "https://rust-reddit-fediverse/api/v1/posts?type={all, best, front}&sort={}&page=1,
|
"id": "https://rust-reddit-fediverse/api/v1/posts?type={all, best, front}&sort={}&page=1,
|
||||||
"partOf": "http://example.org/foo",
|
"partOf": "http://example.org/foo",
|
||||||
|
@ -125,11 +128,9 @@
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
### [Comment Listings / Ordered CollectionPage](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-orderedcollectionpage)
|
### [Comment Listings / Ordered CollectionPage](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-orderedcollectionpage)
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Page 1 of comments for",
|
|
||||||
"type": "OrderedCollectionPage",
|
"type": "OrderedCollectionPage",
|
||||||
"id": "https://rust-reddit-fediverse/api/v1/comments?type={all,user,community,post,parent_comment}&id=1&page=1,
|
"id": "https://rust-reddit-fediverse/api/v1/comments?type={all,user,community,post,parent_comment}&id=1&page=1,
|
||||||
"partOf": "http://example.org/foo",
|
"partOf": "http://example.org/foo",
|
||||||
|
@ -147,13 +148,16 @@
|
||||||
```
|
```
|
||||||
## Actions
|
## Actions
|
||||||
|
|
||||||
|
- These are all posts to a user's outbox.
|
||||||
|
- The server then creates a post to the necessary inbox of the recipient, or the followers.
|
||||||
|
- Whenever a user accesses the site, they do a get from their inbox.
|
||||||
|
|
||||||
### Comments
|
### Comments
|
||||||
|
|
||||||
#### [Create](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-create)
|
#### [Create](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-create)
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally created a note",
|
|
||||||
"type": "Create",
|
"type": "Create",
|
||||||
"actor": id,
|
"actor": id,
|
||||||
"object": comment_id, or post_id
|
"object": comment_id, or post_id
|
||||||
|
@ -164,7 +168,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally deleted a note",
|
|
||||||
"type": "Delete",
|
"type": "Delete",
|
||||||
"actor": id,
|
"actor": id,
|
||||||
"object": comment_id, or post_id
|
"object": comment_id, or post_id
|
||||||
|
@ -174,7 +177,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally created a note",
|
|
||||||
"type": "Create",
|
"type": "Create",
|
||||||
"actor": id,
|
"actor": id,
|
||||||
"object": comment_id, or post_id
|
"object": comment_id, or post_id
|
||||||
|
@ -186,7 +188,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally read a comment",
|
|
||||||
"type": "Read",
|
"type": "Read",
|
||||||
"actor": user_id
|
"actor": user_id
|
||||||
"object": comment_id
|
"object": comment_id
|
||||||
|
@ -194,10 +195,10 @@
|
||||||
```
|
```
|
||||||
|
|
||||||
#### [Like](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-like)
|
#### [Like](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-like)
|
||||||
|
- TODO: Should likes be notifications? IE, have a to?
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally liked a comment",
|
|
||||||
"type": "Like",
|
"type": "Like",
|
||||||
"actor": user_id
|
"actor": user_id
|
||||||
"object": comment_id
|
"object": comment_id
|
||||||
|
@ -208,7 +209,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally disliked a comment",
|
|
||||||
"type": "Dislike",
|
"type": "Dislike",
|
||||||
"actor": user_id
|
"actor": user_id
|
||||||
"object": comment_id
|
"object": comment_id
|
||||||
|
@ -221,9 +221,9 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally created a post",
|
|
||||||
"type": "Create",
|
"type": "Create",
|
||||||
"actor": id,
|
"actor": id,
|
||||||
|
"to": community_id/followers
|
||||||
"object": post_id
|
"object": post_id
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -231,7 +231,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally deleted a post",
|
|
||||||
"type": "Delete",
|
"type": "Delete",
|
||||||
"actor": id,
|
"actor": id,
|
||||||
"object": comment_id, or post_id
|
"object": comment_id, or post_id
|
||||||
|
@ -242,7 +241,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally created a post",
|
|
||||||
"type": "Create",
|
"type": "Create",
|
||||||
"actor": id,
|
"actor": id,
|
||||||
"object": comment_id, or post_id
|
"object": comment_id, or post_id
|
||||||
|
@ -253,7 +251,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally read a post",
|
|
||||||
"type": "Read",
|
"type": "Read",
|
||||||
"actor": user_id
|
"actor": user_id
|
||||||
"object": post_id
|
"object": post_id
|
||||||
|
@ -265,7 +262,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally created a community",
|
|
||||||
"type": "Create",
|
"type": "Create",
|
||||||
"actor": id,
|
"actor": id,
|
||||||
"object": community_id
|
"object": community_id
|
||||||
|
@ -275,7 +271,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally deleted a community",
|
|
||||||
"type": "Delete",
|
"type": "Delete",
|
||||||
"actor": id,
|
"actor": id,
|
||||||
"object": community_id
|
"object": community_id
|
||||||
|
@ -286,7 +281,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally created a community",
|
|
||||||
"type": "Create",
|
"type": "Create",
|
||||||
"actor": id,
|
"actor": id,
|
||||||
"object": community_id
|
"object": community_id
|
||||||
|
@ -294,11 +288,29 @@
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### [Join](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-join)
|
#### [Follow / Subscribe](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-follow)
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
"type": "Follow",
|
||||||
|
"actor": id
|
||||||
|
"object": community_id
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### [Ignore/ Unsubscribe](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-ignore)
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
"type": "Follow",
|
||||||
|
"actor": id
|
||||||
|
"object": community_id
|
||||||
|
}
|
||||||
|
```
|
||||||
|
#### [Join / Become a Mod](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-join)
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally joined a community",
|
|
||||||
"type": "Join",
|
"type": "Join",
|
||||||
"actor": user_id,
|
"actor": user_id,
|
||||||
"object": community_id
|
"object": community_id
|
||||||
|
@ -309,7 +321,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally left a community",
|
|
||||||
"type": "Leave",
|
"type": "Leave",
|
||||||
"actor": user_id,
|
"actor": user_id,
|
||||||
"object": community_id
|
"object": community_id
|
||||||
|
@ -321,7 +332,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "The moderator blocked Sally from a group",
|
|
||||||
"type": "Remove",
|
"type": "Remove",
|
||||||
"actor": mod_id,
|
"actor": mod_id,
|
||||||
"object": user_id,
|
"object": user_id,
|
||||||
|
@ -333,7 +343,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally deleted a users comment",
|
|
||||||
"type": "Delete",
|
"type": "Delete",
|
||||||
"actor": id,
|
"actor": id,
|
||||||
"object": community_id
|
"object": community_id
|
||||||
|
@ -344,7 +353,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "Sally invited John to mod a community",
|
|
||||||
"type": "Invite",
|
"type": "Invite",
|
||||||
"id": "https://rust-reddit-fediverse/api/v1/invite/1",
|
"id": "https://rust-reddit-fediverse/api/v1/invite/1",
|
||||||
"actor": sally_id,
|
"actor": sally_id,
|
||||||
|
@ -356,7 +364,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "John Accepted an invitation to mod a community",
|
|
||||||
"type": "Accept",
|
"type": "Accept",
|
||||||
"actor": john_id,
|
"actor": john_id,
|
||||||
"object": invite_id
|
"object": invite_id
|
||||||
|
@ -366,7 +373,6 @@
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
"summary": "John Rejected an invitation to mod a community",
|
|
||||||
"type": "Reject",
|
"type": "Reject",
|
||||||
"actor": john_id,
|
"actor": john_id,
|
||||||
"object": invite_id
|
"object": invite_id
|
||||||
|
|
|
@ -12,6 +12,8 @@ We have a twitter alternative (mastodon), a facebook alternative (friendica), so
|
||||||
- Must have communities.
|
- Must have communities.
|
||||||
- Must have threaded comments.
|
- Must have threaded comments.
|
||||||
- Must be federated: liking and following communities across instances.
|
- Must be federated: liking and following communities across instances.
|
||||||
|
- Be live-updating: have a right pane for new comments, and a main pain for the full threaded view.
|
||||||
|
- Use websockets for post / gets to your own instance.
|
||||||
|
|
||||||
## Questions
|
## Questions
|
||||||
- How does voting work? Should we go back to the old way of showing up and downvote counts? Or just a score?
|
- How does voting work? Should we go back to the old way of showing up and downvote counts? Or just a score?
|
||||||
|
@ -25,5 +27,7 @@ We have a twitter alternative (mastodon), a facebook alternative (friendica), so
|
||||||
- Use the [activitypub crate.](https://docs.rs/activitypub/0.1.4/activitypub/)
|
- Use the [activitypub crate.](https://docs.rs/activitypub/0.1.4/activitypub/)
|
||||||
- https://docs.rs/activitypub/0.1.4/activitypub/
|
- https://docs.rs/activitypub/0.1.4/activitypub/
|
||||||
- [Activitypub vocab.](https://www.w3.org/TR/activitystreams-vocabulary/)
|
- [Activitypub vocab.](https://www.w3.org/TR/activitystreams-vocabulary/)
|
||||||
|
- [Activitypub main](https://www.w3.org/TR/activitypub/)
|
||||||
- [Diesel to Postgres data types](https://kotiri.com/2018/01/31/postgresql-diesel-rust-types.html)
|
- [Diesel to Postgres data types](https://kotiri.com/2018/01/31/postgresql-diesel-rust-types.html)
|
||||||
- [helpful diesel examples](http://siciarz.net/24-days-rust-diesel/)
|
- [helpful diesel examples](http://siciarz.net/24-days-rust-diesel/)
|
||||||
|
- [Mastodan public key server example](https://blog.joinmastodon.org/2018/06/how-to-implement-a-basic-activitypub-server/)
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
create table user_ (
|
create table user_ (
|
||||||
id serial primary key,
|
id serial primary key,
|
||||||
name varchar(20) not null,
|
name varchar(20) not null,
|
||||||
password_encrypted varchar(200) not null,
|
preferred_username varchar(20),
|
||||||
email varchar(200),
|
password_encrypted text not null,
|
||||||
|
email text,
|
||||||
icon bytea,
|
icon bytea,
|
||||||
startTime timestamp not null default now()
|
start_time timestamp not null default now()
|
||||||
)
|
);
|
||||||
|
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
drop table community
|
drop table community_user;
|
||||||
|
drop table community_follower;
|
||||||
|
drop table community;
|
||||||
|
|
|
@ -1,5 +1,19 @@
|
||||||
create table community (
|
create table community (
|
||||||
id serial primary key,
|
id serial primary key,
|
||||||
name varchar(20) not null,
|
name varchar(20) not null,
|
||||||
starttime timestamp not null default now()
|
start_time timestamp not null default now()
|
||||||
)
|
);
|
||||||
|
|
||||||
|
create table community_user (
|
||||||
|
id serial primary key,
|
||||||
|
community_id int references community on update cascade on delete cascade not null,
|
||||||
|
fedi_user_id text not null,
|
||||||
|
start_time timestamp not null default now()
|
||||||
|
);
|
||||||
|
|
||||||
|
create table community_follower (
|
||||||
|
id serial primary key,
|
||||||
|
community_id int references community on update cascade on delete cascade not null,
|
||||||
|
fedi_user_id text not null,
|
||||||
|
start_time timestamp not null default now()
|
||||||
|
);
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
drop table community_user;
|
|
||||||
-- drop type community_user_type;
|
|
|
@ -1,10 +0,0 @@
|
||||||
-- No support for types yet, so just do 0,1,2
|
|
||||||
-- create type community_user_type as enum ('creator', 'moderator', 'user');
|
|
||||||
|
|
||||||
create table community_user (
|
|
||||||
id serial primary key,
|
|
||||||
fedi_user_id varchar(100) not null,
|
|
||||||
community_id int references community on update cascade on delete cascade,
|
|
||||||
community_user_type smallint not null default 2,
|
|
||||||
starttime timestamp not null default now()
|
|
||||||
)
|
|
3
server/migrations/2019-03-03-163336_create_post/down.sql
Normal file
3
server/migrations/2019-03-03-163336_create_post/down.sql
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
drop table post_like;
|
||||||
|
drop table post_dislike;
|
||||||
|
drop table post;
|
22
server/migrations/2019-03-03-163336_create_post/up.sql
Normal file
22
server/migrations/2019-03-03-163336_create_post/up.sql
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
create table post (
|
||||||
|
id serial primary key,
|
||||||
|
name varchar(100) not null,
|
||||||
|
url text not null,
|
||||||
|
attributed_to text not null,
|
||||||
|
start_time timestamp not null default now()
|
||||||
|
);
|
||||||
|
|
||||||
|
create table post_like (
|
||||||
|
id serial primary key,
|
||||||
|
fedi_user_id text not null,
|
||||||
|
post_id int references post on update cascade on delete cascade,
|
||||||
|
start_time timestamp not null default now()
|
||||||
|
);
|
||||||
|
|
||||||
|
create table post_dislike (
|
||||||
|
id serial primary key,
|
||||||
|
fedi_user_id text not null,
|
||||||
|
post_id int references post on update cascade on delete cascade,
|
||||||
|
start_time timestamp not null default now()
|
||||||
|
);
|
||||||
|
|
197
server/src/actions/community.rs
Normal file
197
server/src/actions/community.rs
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
extern crate diesel;
|
||||||
|
use schema::{community, community_user, community_follower};
|
||||||
|
use diesel::*;
|
||||||
|
use diesel::result::Error;
|
||||||
|
use {Crud, Followable, Joinable};
|
||||||
|
|
||||||
|
#[derive(Queryable, Identifiable, PartialEq, Debug)]
|
||||||
|
#[table_name="community"]
|
||||||
|
pub struct Community {
|
||||||
|
pub id: i32,
|
||||||
|
pub name: String,
|
||||||
|
pub start_time: chrono::NaiveDateTime
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable, AsChangeset, Clone, Copy)]
|
||||||
|
#[table_name="community"]
|
||||||
|
pub struct CommunityForm<'a> {
|
||||||
|
pub name: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
|
||||||
|
#[belongs_to(Community)]
|
||||||
|
#[table_name = "community_user"]
|
||||||
|
pub struct CommunityUser {
|
||||||
|
pub id: i32,
|
||||||
|
pub community_id: i32,
|
||||||
|
pub fedi_user_id: String,
|
||||||
|
pub start_time: chrono::NaiveDateTime
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable, AsChangeset, Clone, Copy)]
|
||||||
|
#[table_name="community_user"]
|
||||||
|
pub struct CommunityUserForm<'a> {
|
||||||
|
pub community_id: &'a i32,
|
||||||
|
pub fedi_user_id: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
|
||||||
|
#[belongs_to(Community)]
|
||||||
|
#[table_name = "community_follower"]
|
||||||
|
pub struct CommunityFollower {
|
||||||
|
pub id: i32,
|
||||||
|
pub community_id: i32,
|
||||||
|
pub fedi_user_id: String,
|
||||||
|
pub start_time: chrono::NaiveDateTime
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable, AsChangeset, Clone, Copy)]
|
||||||
|
#[table_name="community_follower"]
|
||||||
|
pub struct CommunityFollowerForm<'a> {
|
||||||
|
pub community_id: &'a i32,
|
||||||
|
pub fedi_user_id: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<'a> Crud<CommunityForm<'a>> for Community {
|
||||||
|
fn read(conn: &PgConnection, community_id: i32) -> Community {
|
||||||
|
use schema::community::dsl::*;
|
||||||
|
community.find(community_id)
|
||||||
|
.first::<Community>(conn)
|
||||||
|
.expect("Error in query")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete(conn: &PgConnection, community_id: i32) -> usize {
|
||||||
|
use schema::community::dsl::*;
|
||||||
|
diesel::delete(community.find(community_id))
|
||||||
|
.execute(conn)
|
||||||
|
.expect("Error deleting.")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create(conn: &PgConnection, new_community: CommunityForm) -> Result<Community, Error> {
|
||||||
|
use schema::community::dsl::*;
|
||||||
|
insert_into(community)
|
||||||
|
.values(new_community)
|
||||||
|
.get_result::<Community>(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(conn: &PgConnection, community_id: i32, new_community: CommunityForm) -> Community {
|
||||||
|
use schema::community::dsl::*;
|
||||||
|
diesel::update(community.find(community_id))
|
||||||
|
.set(new_community)
|
||||||
|
.get_result::<Community>(conn)
|
||||||
|
.expect(&format!("Unable to find {}", community_id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Followable<CommunityFollowerForm<'a>> for CommunityFollower {
|
||||||
|
fn follow(conn: &PgConnection, community_follower_form: CommunityFollowerForm) -> Result<CommunityFollower, Error> {
|
||||||
|
use schema::community_follower::dsl::*;
|
||||||
|
insert_into(community_follower)
|
||||||
|
.values(community_follower_form)
|
||||||
|
.get_result::<CommunityFollower>(conn)
|
||||||
|
}
|
||||||
|
fn ignore(conn: &PgConnection, community_follower_form: CommunityFollowerForm) -> usize {
|
||||||
|
use schema::community_follower::dsl::*;
|
||||||
|
diesel::delete(community_follower
|
||||||
|
.filter(community_id.eq(community_follower_form.community_id))
|
||||||
|
.filter(fedi_user_id.eq(community_follower_form.fedi_user_id)))
|
||||||
|
.execute(conn)
|
||||||
|
.expect("Error deleting.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Joinable<CommunityUserForm<'a>> for CommunityUser {
|
||||||
|
fn join(conn: &PgConnection, community_user_form: CommunityUserForm) -> Result<CommunityUser, Error> {
|
||||||
|
use schema::community_user::dsl::*;
|
||||||
|
insert_into(community_user)
|
||||||
|
.values(community_user_form)
|
||||||
|
.get_result::<CommunityUser>(conn)
|
||||||
|
}
|
||||||
|
fn leave(conn: &PgConnection, community_user_form: CommunityUserForm) -> usize {
|
||||||
|
use schema::community_user::dsl::*;
|
||||||
|
diesel::delete(community_user
|
||||||
|
.filter(community_id.eq(community_user_form.community_id))
|
||||||
|
.filter(fedi_user_id.eq(community_user_form.fedi_user_id)))
|
||||||
|
.execute(conn)
|
||||||
|
.expect("Error deleting.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use establish_connection;
|
||||||
|
use super::*;
|
||||||
|
use actions::user::*;
|
||||||
|
use Crud;
|
||||||
|
#[test]
|
||||||
|
fn test_crud() {
|
||||||
|
let conn = establish_connection();
|
||||||
|
|
||||||
|
let new_community = CommunityForm {
|
||||||
|
name: "TIL".into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_community = Community::create(&conn, new_community).unwrap();
|
||||||
|
|
||||||
|
let expected_community = Community {
|
||||||
|
id: inserted_community.id,
|
||||||
|
name: "TIL".into(),
|
||||||
|
start_time: inserted_community.start_time
|
||||||
|
};
|
||||||
|
|
||||||
|
let new_user = UserForm {
|
||||||
|
name: "thom".into(),
|
||||||
|
preferred_username: None,
|
||||||
|
password_encrypted: "nope".into(),
|
||||||
|
email: None
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_user = User_::create(&conn, new_user).unwrap();
|
||||||
|
|
||||||
|
let community_follower_form = CommunityFollowerForm {
|
||||||
|
community_id: &inserted_community.id,
|
||||||
|
fedi_user_id: "test".into()
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_community_follower = CommunityFollower::follow(&conn, community_follower_form).unwrap();
|
||||||
|
|
||||||
|
let expected_community_follower = CommunityFollower {
|
||||||
|
id: inserted_community_follower.id,
|
||||||
|
community_id: inserted_community.id,
|
||||||
|
fedi_user_id: "test".into(),
|
||||||
|
start_time: inserted_community_follower.start_time
|
||||||
|
};
|
||||||
|
|
||||||
|
let community_user_form = CommunityUserForm {
|
||||||
|
community_id: &inserted_community.id,
|
||||||
|
fedi_user_id: "test".into()
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_community_user = CommunityUser::join(&conn, community_user_form).unwrap();
|
||||||
|
|
||||||
|
let expected_community_user = CommunityUser {
|
||||||
|
id: inserted_community_user.id,
|
||||||
|
community_id: inserted_community.id,
|
||||||
|
fedi_user_id: "test".into(),
|
||||||
|
start_time: inserted_community_user.start_time
|
||||||
|
};
|
||||||
|
|
||||||
|
let read_community = Community::read(&conn, inserted_community.id);
|
||||||
|
let updated_community = Community::update(&conn, inserted_community.id, new_community);
|
||||||
|
let ignored_community = CommunityFollower::ignore(&conn, community_follower_form);
|
||||||
|
let left_community = CommunityUser::leave(&conn, community_user_form);
|
||||||
|
let num_deleted = Community::delete(&conn, inserted_community.id);
|
||||||
|
User_::delete(&conn, inserted_user.id);
|
||||||
|
|
||||||
|
assert_eq!(expected_community, read_community);
|
||||||
|
assert_eq!(expected_community, inserted_community);
|
||||||
|
assert_eq!(expected_community, updated_community);
|
||||||
|
assert_eq!(expected_community_follower, inserted_community_follower);
|
||||||
|
assert_eq!(expected_community_user, inserted_community_user);
|
||||||
|
assert_eq!(1, ignored_community);
|
||||||
|
assert_eq!(1, left_community);
|
||||||
|
assert_eq!(1, num_deleted);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,3 @@
|
||||||
use diesel::*;
|
|
||||||
pub mod user;
|
pub mod user;
|
||||||
|
pub mod community;
|
||||||
|
pub mod post;
|
||||||
|
|
95
server/src/actions/post.rs
Normal file
95
server/src/actions/post.rs
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
extern crate diesel;
|
||||||
|
use schema::user_;
|
||||||
|
use diesel::*;
|
||||||
|
use diesel::result::Error;
|
||||||
|
use schema::user_::dsl::*;
|
||||||
|
|
||||||
|
#[derive(Queryable, PartialEq, Debug)]
|
||||||
|
pub struct User_ {
|
||||||
|
pub id: i32,
|
||||||
|
pub name: String,
|
||||||
|
pub preferred_username: Option<String>,
|
||||||
|
pub password_encrypted: String,
|
||||||
|
pub email: Option<String>,
|
||||||
|
pub icon: Option<Vec<u8>>,
|
||||||
|
pub start_time: chrono::NaiveDateTime
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable, AsChangeset, Clone, Copy)]
|
||||||
|
#[table_name="user_"]
|
||||||
|
pub struct NewUser<'a> {
|
||||||
|
pub name: &'a str,
|
||||||
|
pub preferred_username: Option<&'a str>,
|
||||||
|
pub password_encrypted: &'a str,
|
||||||
|
pub email: Option<&'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(conn: &PgConnection, user_id: i32) -> User_ {
|
||||||
|
user_.find(user_id)
|
||||||
|
.first::<User_>(conn)
|
||||||
|
.expect("Error in query")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete(conn: &PgConnection, user_id: i32) -> usize {
|
||||||
|
diesel::delete(user_.find(user_id))
|
||||||
|
.execute(conn)
|
||||||
|
.expect("Error deleting.")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create(conn: &PgConnection, new_user: &NewUser) -> Result<User_, Error> {
|
||||||
|
let mut edited_user = new_user.clone();
|
||||||
|
// Add the rust crypt
|
||||||
|
edited_user.password_encrypted = "here";
|
||||||
|
// edited_user.password_encrypted;
|
||||||
|
insert_into(user_)
|
||||||
|
.values(edited_user)
|
||||||
|
.get_result::<User_>(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(conn: &PgConnection, user_id: i32, new_user: &NewUser) -> User_ {
|
||||||
|
let mut edited_user = new_user.clone();
|
||||||
|
edited_user.password_encrypted = "here";
|
||||||
|
diesel::update(user_.find(user_id))
|
||||||
|
.set(edited_user)
|
||||||
|
.get_result::<User_>(conn)
|
||||||
|
.expect(&format!("Unable to find user {}", user_id))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use establish_connection;
|
||||||
|
use super::*;
|
||||||
|
#[test]
|
||||||
|
fn test_crud() {
|
||||||
|
let conn = establish_connection();
|
||||||
|
|
||||||
|
let new_user = NewUser {
|
||||||
|
name: "thom".into(),
|
||||||
|
preferred_username: None,
|
||||||
|
password_encrypted: "nope".into(),
|
||||||
|
email: None
|
||||||
|
};
|
||||||
|
|
||||||
|
let inserted_user = create(&conn, &new_user).unwrap();
|
||||||
|
|
||||||
|
let expected_user = User_ {
|
||||||
|
id: inserted_user.id,
|
||||||
|
name: "thom".into(),
|
||||||
|
preferred_username: None,
|
||||||
|
password_encrypted: "here".into(),
|
||||||
|
email: None,
|
||||||
|
icon: None,
|
||||||
|
start_time: inserted_user.start_time
|
||||||
|
};
|
||||||
|
|
||||||
|
let read_user = read(&conn, inserted_user.id);
|
||||||
|
let updated_user = update(&conn, inserted_user.id, &new_user);
|
||||||
|
let num_deleted = delete(&conn, inserted_user.id);
|
||||||
|
|
||||||
|
assert_eq!(expected_user, read_user);
|
||||||
|
assert_eq!(expected_user, inserted_user);
|
||||||
|
assert_eq!(expected_user, updated_user);
|
||||||
|
assert_eq!(1, num_deleted);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
80
server/src/actions/src/schema.rs
Normal file
80
server/src/actions/src/schema.rs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
table! {
|
||||||
|
community (id) {
|
||||||
|
id -> Int4,
|
||||||
|
name -> Varchar,
|
||||||
|
start_time -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
community_follower (id) {
|
||||||
|
id -> Int4,
|
||||||
|
fedi_user_id -> Text,
|
||||||
|
community_id -> Nullable<Int4>,
|
||||||
|
start_time -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
community_user (id) {
|
||||||
|
id -> Int4,
|
||||||
|
fedi_user_id -> Text,
|
||||||
|
community_id -> Nullable<Int4>,
|
||||||
|
start_time -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
post (id) {
|
||||||
|
id -> Int4,
|
||||||
|
name -> Varchar,
|
||||||
|
url -> Text,
|
||||||
|
attributed_to -> Text,
|
||||||
|
start_time -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
post_dislike (id) {
|
||||||
|
id -> Int4,
|
||||||
|
fedi_user_id -> Text,
|
||||||
|
post_id -> Nullable<Int4>,
|
||||||
|
start_time -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
post_like (id) {
|
||||||
|
id -> Int4,
|
||||||
|
fedi_user_id -> Text,
|
||||||
|
post_id -> Nullable<Int4>,
|
||||||
|
start_time -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
user_ (id) {
|
||||||
|
id -> Int4,
|
||||||
|
name -> Varchar,
|
||||||
|
preferred_username -> Nullable<Varchar>,
|
||||||
|
password_encrypted -> Text,
|
||||||
|
email -> Nullable<Text>,
|
||||||
|
icon -> Nullable<Bytea>,
|
||||||
|
start_time -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
joinable!(community_follower -> community (community_id));
|
||||||
|
joinable!(community_user -> community (community_id));
|
||||||
|
joinable!(post_dislike -> post (post_id));
|
||||||
|
joinable!(post_like -> post (post_id));
|
||||||
|
|
||||||
|
allow_tables_to_appear_in_same_query!(
|
||||||
|
community,
|
||||||
|
community_follower,
|
||||||
|
community_user,
|
||||||
|
post,
|
||||||
|
post_dislike,
|
||||||
|
post_like,
|
||||||
|
user_,
|
||||||
|
);
|
|
@ -1,71 +1,95 @@
|
||||||
extern crate diesel;
|
extern crate diesel;
|
||||||
|
extern crate activitypub;
|
||||||
use schema::user_;
|
use schema::user_;
|
||||||
use diesel::*;
|
use diesel::*;
|
||||||
use diesel::result::Error;
|
use diesel::result::Error;
|
||||||
use schema::user_::dsl::*;
|
use schema::user_::dsl::*;
|
||||||
|
// use self::activitypub::{context, actor::Person};
|
||||||
use Crud;
|
use Crud;
|
||||||
|
|
||||||
#[derive(Queryable, PartialEq, Debug)]
|
#[derive(Queryable, Identifiable, PartialEq, Debug)]
|
||||||
|
#[table_name="user_"]
|
||||||
pub struct User_ {
|
pub struct User_ {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
pub preferred_username: Option<String>,
|
||||||
pub password_encrypted: String,
|
pub password_encrypted: String,
|
||||||
pub email: Option<String>,
|
pub email: Option<String>,
|
||||||
pub icon: Option<Vec<u8>>,
|
pub icon: Option<Vec<u8>>,
|
||||||
pub start_time: chrono::NaiveDateTime
|
pub start_time: chrono::NaiveDateTime
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Insertable)]
|
#[derive(Insertable, AsChangeset, Clone, Copy)]
|
||||||
#[table_name="user_"]
|
#[table_name="user_"]
|
||||||
pub struct NewUser<'a> {
|
pub struct UserForm<'a> {
|
||||||
pub name: &'a str,
|
pub name: &'a str,
|
||||||
|
pub preferred_username: Option<&'a str>,
|
||||||
pub password_encrypted: &'a str,
|
pub password_encrypted: &'a str,
|
||||||
pub email: Option<&'a str>,
|
pub email: Option<&'a str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Crud for User_ {
|
impl<'a> Crud<UserForm<'a>> for User_ {
|
||||||
fn read(conn: &PgConnection, user_id: i32) -> User_ {
|
fn read(conn: &PgConnection, user_id: i32) -> User_ {
|
||||||
user_.find(user_id)
|
user_.find(user_id)
|
||||||
.first::<User_>(conn)
|
.first::<User_>(conn)
|
||||||
.expect("Error in query")
|
.expect("Error in query")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete(conn: &PgConnection, user_id: i32) -> usize {
|
fn delete(conn: &PgConnection, user_id: i32) -> usize {
|
||||||
diesel::delete(user_.find(user_id))
|
diesel::delete(user_.find(user_id))
|
||||||
.execute(conn)
|
.execute(conn)
|
||||||
.expect("Error deleting.")
|
.expect("Error deleting.")
|
||||||
}
|
}
|
||||||
|
fn create(conn: &PgConnection, form: UserForm) -> Result<User_, Error> {
|
||||||
// fn create<NewUser>(conn: &PgConnection, mut new_user: NewUser) -> Result<User_, Error> {
|
let mut edited_user = form.clone();
|
||||||
}
|
// Add the rust crypt
|
||||||
|
edited_user.password_encrypted = "here";
|
||||||
pub fn create(conn: &PgConnection, mut new_user: NewUser) -> Result<User_, Error> {
|
// edited_user.password_encrypted;
|
||||||
new_user.password_encrypted = "here";
|
|
||||||
// new_user.password_encrypted;
|
|
||||||
insert_into(user_)
|
insert_into(user_)
|
||||||
.values(new_user)
|
.values(edited_user)
|
||||||
.get_result(conn)
|
.get_result::<User_>(conn)
|
||||||
|
}
|
||||||
|
fn update(conn: &PgConnection, user_id: i32, form: UserForm) -> User_ {
|
||||||
|
let mut edited_user = form.clone();
|
||||||
|
edited_user.password_encrypted = "here";
|
||||||
|
diesel::update(user_.find(user_id))
|
||||||
|
.set(edited_user)
|
||||||
|
.get_result::<User_>(conn)
|
||||||
|
.expect(&format!("Unable to find user {}", user_id))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// pub fn person(user: &User_) -> Person {
|
||||||
|
// let mut person = Person::default();
|
||||||
|
// person.object_props.set_context_object(context());
|
||||||
|
// person.ap_actor_props.set_preferred_username_string("set".into());
|
||||||
|
|
||||||
|
// person
|
||||||
|
// }
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use establish_connection;
|
use establish_connection;
|
||||||
use super::*;
|
use super::{User_, UserForm};
|
||||||
|
use Crud;
|
||||||
#[test]
|
#[test]
|
||||||
fn test_crud() {
|
fn test_crud() {
|
||||||
let conn = establish_connection();
|
let conn = establish_connection();
|
||||||
|
|
||||||
let new_user = NewUser {
|
let new_user = UserForm {
|
||||||
name: "thom".into(),
|
name: "thom".into(),
|
||||||
|
preferred_username: None,
|
||||||
password_encrypted: "nope".into(),
|
password_encrypted: "nope".into(),
|
||||||
email: None
|
email: None
|
||||||
};
|
};
|
||||||
|
|
||||||
let inserted_user = create(&conn, new_user).unwrap();
|
let inserted_user = User_::create(&conn, new_user).unwrap();
|
||||||
|
|
||||||
let expected_user = User_ {
|
let expected_user = User_ {
|
||||||
id: inserted_user.id,
|
id: inserted_user.id,
|
||||||
name: "thom".into(),
|
name: "thom".into(),
|
||||||
|
preferred_username: None,
|
||||||
password_encrypted: "here".into(),
|
password_encrypted: "here".into(),
|
||||||
email: None,
|
email: None,
|
||||||
icon: None,
|
icon: None,
|
||||||
|
@ -73,11 +97,12 @@ mod tests {
|
||||||
};
|
};
|
||||||
|
|
||||||
let read_user = User_::read(&conn, inserted_user.id);
|
let read_user = User_::read(&conn, inserted_user.id);
|
||||||
|
let updated_user = User_::update(&conn, inserted_user.id, new_user);
|
||||||
let num_deleted = User_::delete(&conn, inserted_user.id);
|
let num_deleted = User_::delete(&conn, inserted_user.id);
|
||||||
|
|
||||||
assert_eq!(expected_user, read_user);
|
assert_eq!(expected_user, read_user);
|
||||||
assert_eq!(expected_user, inserted_user);
|
assert_eq!(expected_user, inserted_user);
|
||||||
|
assert_eq!(expected_user, updated_user);
|
||||||
assert_eq!(1, num_deleted);
|
assert_eq!(1, num_deleted);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
extern crate activitypub;
|
|
||||||
extern crate failure;
|
|
||||||
extern crate serde_json;
|
|
||||||
|
|
||||||
// fn user -> Result<(), Error> {
|
|
||||||
|
|
||||||
// }
|
|
|
@ -2,16 +2,35 @@
|
||||||
extern crate diesel;
|
extern crate diesel;
|
||||||
extern crate dotenv;
|
extern crate dotenv;
|
||||||
|
|
||||||
use diesel::prelude::*;
|
use diesel::*;
|
||||||
use diesel::pg::PgConnection;
|
use diesel::pg::PgConnection;
|
||||||
|
use diesel::result::Error;
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
pub mod schema;
|
pub mod schema;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
pub mod activitypub;
|
|
||||||
pub mod actions;
|
pub mod actions;
|
||||||
|
|
||||||
|
// pub trait Likeable;
|
||||||
|
pub trait Crud<T> {
|
||||||
|
fn create(conn: &PgConnection, form: T) -> Result<Self, Error> where Self: Sized;
|
||||||
|
fn read(conn: &PgConnection, id: i32) -> Self;
|
||||||
|
fn update(conn: &PgConnection, id: i32, form: T) -> Self;
|
||||||
|
fn delete(conn: &PgConnection, id: i32) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Followable<T> {
|
||||||
|
fn follow(conn: &PgConnection, form: T) -> Result<Self, Error> where Self: Sized;
|
||||||
|
fn ignore(conn: &PgConnection, form: T) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Joinable<T> {
|
||||||
|
fn join(conn: &PgConnection, form: T) -> Result<Self, Error> where Self: Sized;
|
||||||
|
fn leave(conn: &PgConnection, form: T) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn establish_connection() -> PgConnection {
|
pub fn establish_connection() -> PgConnection {
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
|
|
||||||
|
@ -21,21 +40,3 @@ pub fn establish_connection() -> PgConnection {
|
||||||
.expect(&format!("Error connecting to {}", database_url))
|
.expect(&format!("Error connecting to {}", database_url))
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Crud {
|
|
||||||
fn read(conn: &PgConnection, id: i32) -> Self;
|
|
||||||
fn delete(conn: &PgConnection, id: i32) -> usize;
|
|
||||||
// fn create<T: Insertable>(conn: &PgConnection, item: T) -> Result<Self, Error> where Self: Sized;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
#[test]
|
|
||||||
fn it_works() {
|
|
||||||
assert_eq!(2 + 2, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn db_fetch() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
|
|
||||||
enum CommunityUserType {
|
// enum CommunityUserType {
|
||||||
CREATOR = 0,
|
// CREATOR = 0,
|
||||||
MODERATOR = 1,
|
// MODERATOR = 1,
|
||||||
USER = 2
|
// USER = 2
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl CommunityUserType {
|
// impl CommunityUserType {
|
||||||
fn from_u32(value: u32) -> CommunityUserType {
|
// fn from_u32(value: u32) -> CommunityUserType {
|
||||||
match value {
|
// match value {
|
||||||
0 => CommunityUserType::CREATOR,
|
// 0 => CommunityUserType::CREATOR,
|
||||||
1 => CommunityUserType::MODERATOR,
|
// 1 => CommunityUserType::MODERATOR,
|
||||||
2 => CommunityUserType::USER,
|
// 2 => CommunityUserType::USER,
|
||||||
_ => panic!("Unknown value: {}", value),
|
// _ => panic!("Unknown value: {}", value),
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,53 @@ table! {
|
||||||
community (id) {
|
community (id) {
|
||||||
id -> Int4,
|
id -> Int4,
|
||||||
name -> Varchar,
|
name -> Varchar,
|
||||||
starttime -> Timestamp,
|
start_time -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
community_follower (id) {
|
||||||
|
id -> Int4,
|
||||||
|
community_id -> Int4,
|
||||||
|
fedi_user_id -> Text,
|
||||||
|
start_time -> Timestamp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
table! {
|
table! {
|
||||||
community_user (id) {
|
community_user (id) {
|
||||||
id -> Int4,
|
id -> Int4,
|
||||||
fedi_user_id -> Varchar,
|
community_id -> Int4,
|
||||||
community_id -> Nullable<Int4>,
|
fedi_user_id -> Text,
|
||||||
community_user_type -> Int2,
|
start_time -> Timestamp,
|
||||||
starttime -> Timestamp,
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
post (id) {
|
||||||
|
id -> Int4,
|
||||||
|
name -> Varchar,
|
||||||
|
url -> Text,
|
||||||
|
attributed_to -> Text,
|
||||||
|
start_time -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
post_dislike (id) {
|
||||||
|
id -> Int4,
|
||||||
|
fedi_user_id -> Text,
|
||||||
|
post_id -> Nullable<Int4>,
|
||||||
|
start_time -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table! {
|
||||||
|
post_like (id) {
|
||||||
|
id -> Int4,
|
||||||
|
fedi_user_id -> Text,
|
||||||
|
post_id -> Nullable<Int4>,
|
||||||
|
start_time -> Timestamp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,17 +56,25 @@ table! {
|
||||||
user_ (id) {
|
user_ (id) {
|
||||||
id -> Int4,
|
id -> Int4,
|
||||||
name -> Varchar,
|
name -> Varchar,
|
||||||
password_encrypted -> Varchar,
|
preferred_username -> Nullable<Varchar>,
|
||||||
email -> Nullable<Varchar>,
|
password_encrypted -> Text,
|
||||||
|
email -> Nullable<Text>,
|
||||||
icon -> Nullable<Bytea>,
|
icon -> Nullable<Bytea>,
|
||||||
starttime -> Timestamp,
|
start_time -> Timestamp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
joinable!(community_follower -> community (community_id));
|
||||||
joinable!(community_user -> community (community_id));
|
joinable!(community_user -> community (community_id));
|
||||||
|
joinable!(post_dislike -> post (post_id));
|
||||||
|
joinable!(post_like -> post (post_id));
|
||||||
|
|
||||||
allow_tables_to_appear_in_same_query!(
|
allow_tables_to_appear_in_same_query!(
|
||||||
community,
|
community,
|
||||||
|
community_follower,
|
||||||
community_user,
|
community_user,
|
||||||
|
post,
|
||||||
|
post_dislike,
|
||||||
|
post_like,
|
||||||
user_,
|
user_,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue