proto: added subreddits proto
This commit is contained in:
parent
3ae3606ca1
commit
114a6d5116
|
@ -5,8 +5,8 @@ CREATE TABLE subreddits (
|
|||
disable_scheduler TINYINT NOT NULL DEFAULT 0,
|
||||
"type" VARCHAR(5) NOT NULL DEFAULT 'r',
|
||||
schedule VARCHAR(20) NOT NULL DEFAULT '@daily',
|
||||
countback INT NOT NULL DEFAULT 300,
|
||||
image_cover VARCHAR(255) NOT NULL DEFAULT '',
|
||||
countback BIGINT NOT NULL DEFAULT 300,
|
||||
cover_image_id INTEGER,
|
||||
created_at BIGINT DEFAULT (strftime('%s', 'now')) NOT NULL,
|
||||
updated_at BIGINT DEFAULT (strftime('%s', 'now')) NOT NULL
|
||||
);
|
||||
|
|
|
@ -27,7 +27,10 @@ CREATE TABLE images(
|
|||
CONSTRAINT fk_image_devices_slug
|
||||
FOREIGN KEY (device)
|
||||
REFERENCES devices(slug)
|
||||
ON DELETE CASCADE
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT fk_image_subreddit_cover
|
||||
FOREIGN KEY (id)
|
||||
REFERENCES subreddits(cover_image_id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_subreddit_images_blacklisted ON images(subreddit, blacklisted);
|
||||
|
@ -36,6 +39,21 @@ CREATE INDEX idx_images_nsfw_blacklisted ON images(nsfw, blacklisted);
|
|||
CREATE INDEX idx_images_created_at_nsfw_blacklisted ON images(created_at DESC, nsfw, blacklisted);
|
||||
CREATE INDEX idx_images_blacklisted ON images(blacklisted);
|
||||
CREATE UNIQUE INDEX idx_unique_images_per_device ON images(device, post_name);
|
||||
|
||||
CREATE TRIGGER images_update_timestamp AFTER UPDATE ON images FOR EACH ROW
|
||||
BEGIN
|
||||
UPDATE images SET updated_at = strftime('%s', 'now') WHERE id = old.id;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER images_update_subreddit_cover_on_insert AFTER INSERT ON images FOR EACH ROW
|
||||
BEGIN
|
||||
UPDATE subreddits SET cover_image_id = new.id WHERE name = new.subreddit AND cover_image_id IS NULL;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER images_update_subreddit_cover_on_delete AFTER DELETE ON images FOR EACH ROW
|
||||
BEGIN
|
||||
UPDATE subreddits SET cover_image_id = NULL WHERE cover_image_id = old.id;
|
||||
END;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
|
|
32
schemas/proto/subreddits/v1/create.proto
Normal file
32
schemas/proto/subreddits/v1/create.proto
Normal file
|
@ -0,0 +1,32 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package subreddits.v1;
|
||||
|
||||
import "buf/validate/validate.proto";
|
||||
|
||||
option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1";
|
||||
|
||||
message CreateSubredditRequest {
|
||||
// name of the subreddits to insert.
|
||||
//
|
||||
// accept insensitive casing, but casing
|
||||
// will change to what Reddit has for
|
||||
// consistency.
|
||||
string name = 1 [(buf.validate.field).string.min_len = 1];
|
||||
bool disable_scheduler = 2;
|
||||
SubredditType type = 3;
|
||||
// schedule is cron job spec to set schedule on when
|
||||
// the runner for this subreddit runs.
|
||||
string schedule = 4 [(buf.validate.field).string.min_len = 1];
|
||||
uint32 countback = 5 [(buf.validate.field).uint32.gt = 0];
|
||||
}
|
||||
|
||||
enum SubredditType {
|
||||
SUBREDDIT_TYPE_UNSPECIFIED = 0;
|
||||
SUBREDDIT_TYPE_SUBREDDIT = 1;
|
||||
SUBREDDIT_TYPE_USER = 2;
|
||||
}
|
||||
|
||||
message CreateSubredditResponse {
|
||||
string name = 1;
|
||||
}
|
25
schemas/proto/subreddits/v1/delete.proto
Normal file
25
schemas/proto/subreddits/v1/delete.proto
Normal file
|
@ -0,0 +1,25 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package subreddits.v1;
|
||||
|
||||
import "buf/validate/validate.proto";
|
||||
|
||||
option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1";
|
||||
|
||||
message DeleteSubredditRequest {
|
||||
// name of the subreddit to delete
|
||||
string name = 1 [(buf.validate.field).string.min_len = 1];
|
||||
|
||||
// if true, delete all images associated with the subreddit
|
||||
// from disk as well.
|
||||
bool delete_images = 2;
|
||||
}
|
||||
|
||||
message DeleteSubredditResponse {
|
||||
// name of the subreddit that was deleted.
|
||||
string name = 1;
|
||||
// number of images that were deleted.
|
||||
//
|
||||
// always 0 if delete_images is false.
|
||||
uint32 deleted_images = 2;
|
||||
}
|
42
schemas/proto/subreddits/v1/get.proto
Normal file
42
schemas/proto/subreddits/v1/get.proto
Normal file
|
@ -0,0 +1,42 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package subreddits.v1;
|
||||
|
||||
import "buf/validate/validate.proto";
|
||||
import "subreddits/v1/create.proto";
|
||||
|
||||
option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1";
|
||||
|
||||
message GetSubredditRequest {
|
||||
// name of the subreddit. Case insensitive.
|
||||
//
|
||||
// Returns error on not found.
|
||||
string name = 1 [(buf.validate.field).string.min_len = 1];
|
||||
}
|
||||
|
||||
message GetSubredditResponse {
|
||||
string name = 1;
|
||||
bool disable_scheduler = 2;
|
||||
// type is never unspecified for this response.
|
||||
//
|
||||
// It's always either `SUBREDDIT_TYPE_SUBREDDIT`
|
||||
// or `SUBREDDIT_TYPE_USER`.
|
||||
SubredditType type = 3;
|
||||
string schedule = 4;
|
||||
uint32 countback = 5;
|
||||
// cover_image_id is the id of an image that
|
||||
// acts as the cover for this subreddit.
|
||||
//
|
||||
// May not be present in these kind of situations:
|
||||
//
|
||||
// - The background task runner has not run for this subreddit.
|
||||
// - The image that is used as cover is deleted.
|
||||
// - The subreddit does not contain any images.
|
||||
//
|
||||
// cover_image_id changes after every insert of
|
||||
// new images in that subreddit, so avoid
|
||||
// caching the image for too long.
|
||||
optional uint32 cover_image_id = 6;
|
||||
int64 created_at = 7;
|
||||
int64 updated_at = 8;
|
||||
}
|
19
schemas/proto/subreddits/v1/list.proto
Normal file
19
schemas/proto/subreddits/v1/list.proto
Normal file
|
@ -0,0 +1,19 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package subreddits.v1;
|
||||
|
||||
import "buf/validate/validate.proto";
|
||||
import "subreddits/v1/get.proto";
|
||||
|
||||
option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1";
|
||||
|
||||
message ListSubredditsRequest {
|
||||
// name of the subreddit. Case insensitive.
|
||||
//
|
||||
// Returns error on not found.
|
||||
string name = 1 [(buf.validate.field).string.min_len = 1];
|
||||
}
|
||||
|
||||
message ListSubredditsResponse {
|
||||
repeated GetSubredditResponse images = 1;
|
||||
}
|
17
schemas/proto/subreddits/v1/resolve.proto
Normal file
17
schemas/proto/subreddits/v1/resolve.proto
Normal file
|
@ -0,0 +1,17 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package subreddits.v1;
|
||||
|
||||
import "buf/validate/validate.proto";
|
||||
|
||||
option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1";
|
||||
|
||||
message ResolveSubredditNameRequest {
|
||||
// name of the subreddit to resolve (check existence and casing).
|
||||
string name = 1 [(buf.validate.field).string.min_len = 1];
|
||||
}
|
||||
|
||||
message ResolveSubredditNameResponse {
|
||||
// resolved the actual subreddit name.
|
||||
string resolved = 1;
|
||||
}
|
53
schemas/proto/subreddits/v1/subreddits.proto
Normal file
53
schemas/proto/subreddits/v1/subreddits.proto
Normal file
|
@ -0,0 +1,53 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package subreddits.v1;
|
||||
|
||||
import "subreddits/v1/create.proto";
|
||||
import "subreddits/v1/delete.proto";
|
||||
import "subreddits/v1/get.proto";
|
||||
import "subreddits/v1/list.proto";
|
||||
import "subreddits/v1/resolve.proto";
|
||||
import "subreddits/v1/update.proto";
|
||||
|
||||
option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1";
|
||||
|
||||
service SubredditsService {
|
||||
// CreateSubreddit creates a new subreddit
|
||||
//
|
||||
// Returns the subreddit name.
|
||||
//
|
||||
// Returns the following error codes:
|
||||
// - connect.CodeAlreadyExists if subreddit with the same name already exists.
|
||||
// - connect.CodeInvalidArgument if validation failed, e.g. Invalid schedule cron format.
|
||||
// - connect.CodeNotFound if the subreddit does not exist.
|
||||
rpc CreateSubreddit(CreateSubredditRequest) returns (CreateSubredditResponse);
|
||||
|
||||
// GetSubreddit returns a subreddit by its name.
|
||||
//
|
||||
// Returns error with connect.CodeNotFound if subreddit does not exist.
|
||||
rpc GetSubreddit(GetSubredditRequest) returns (GetSubredditResponse);
|
||||
|
||||
// ListSubreddits returns a list of subreddits.
|
||||
rpc ListSubreddits(ListSubredditsRequest) returns (ListSubredditsResponse);
|
||||
|
||||
// UpdateSubreddit updates a subreddit.
|
||||
//
|
||||
// Only the fields that are set in the request will be updated.
|
||||
//
|
||||
// Returns error with connect.CodeNotFound if subreddit does not exist.
|
||||
rpc UpdateSubreddit(UpdateSubredditRequest) returns (UpdateSubredditResponse);
|
||||
|
||||
// DeleteSubreddit deletes a subreddit.
|
||||
//
|
||||
// Returns error with connect.CodeNotFound if subreddit does not exist.
|
||||
rpc DeleteSubreddit(DeleteSubredditRequest) returns (DeleteSubredditResponse);
|
||||
|
||||
// ResolveSubredditName resolves the given subreddit name.
|
||||
//
|
||||
// The returned resolved_name is the name that is actually
|
||||
// used in Reddit.
|
||||
//
|
||||
// Returns error with connect.CodeNotFound if subreddit does not exist.
|
||||
// So this rpc endpoint also acts to check subreddit's existence.
|
||||
rpc ResolveSubredditName(ResolveSubredditNameRequest) returns (ResolveSubredditNameResponse);
|
||||
}
|
24
schemas/proto/subreddits/v1/update.proto
Normal file
24
schemas/proto/subreddits/v1/update.proto
Normal file
|
@ -0,0 +1,24 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package subreddits.v1;
|
||||
|
||||
import "buf/validate/validate.proto";
|
||||
|
||||
option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1";
|
||||
|
||||
message UpdateSubredditRequest {
|
||||
// The name of the subreddit to update.
|
||||
string name = 1 [(buf.validate.field).string.min_len = 1];
|
||||
SubredditSetter set = 2;
|
||||
}
|
||||
|
||||
message SubredditSetter {
|
||||
optional bool disable_scheduler = 1;
|
||||
optional string schedule = 2 [(buf.validate.field).string.min_len = 1];
|
||||
optional int64 countback = 3 [(buf.validate.field).int64.gt = 0];
|
||||
}
|
||||
|
||||
message UpdateSubredditResponse {
|
||||
// The updated subreddit.
|
||||
string name = 1;
|
||||
}
|
Loading…
Reference in a new issue