diff --git a/crates/db_schema/replaceable_schema/triggers.sql b/crates/db_schema/replaceable_schema/triggers.sql index 4607c658d..08e9dcc08 100644 --- a/crates/db_schema/replaceable_schema/triggers.sql +++ b/crates/db_schema/replaceable_schema/triggers.sql @@ -868,3 +868,35 @@ CALL r.create_inbox_combined_trigger ('person_post_mention'); CALL r.create_inbox_combined_trigger ('private_message'); +-- search: (post, comment, community, person) +CREATE PROCEDURE r.create_search_combined_trigger (table_name text) +LANGUAGE plpgsql +AS $a$ +BEGIN + EXECUTE replace($b$ CREATE FUNCTION r.search_combined_thing_insert ( ) + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ + BEGIN + -- TODO need to figure out how to do the other columns here + INSERT INTO search_combined (published, thing_id) + VALUES (NEW.published, NEW.id); + RETURN NEW; + END $$; + CREATE TRIGGER search_combined + AFTER INSERT ON thing + FOR EACH ROW + EXECUTE FUNCTION r.search_combined_thing_insert ( ); + $b$, + 'thing', + table_name); +END; +$a$; + +CALL r.create_search_combined_trigger ('post'); + +CALL r.create_search_combined_trigger ('comment'); + +CALL r.create_search_combined_trigger ('community'); + +CALL r.create_search_combined_trigger ('person'); diff --git a/crates/db_schema/src/newtypes.rs b/crates/db_schema/src/newtypes.rs index 711d83684..1b6ede97a 100644 --- a/crates/db_schema/src/newtypes.rs +++ b/crates/db_schema/src/newtypes.rs @@ -216,6 +216,12 @@ pub struct ModlogCombinedId(i32); /// The inbox combined id pub struct InboxCombinedId(i32); +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)] +#[cfg_attr(feature = "full", derive(DieselNewType, TS))] +#[cfg_attr(feature = "full", ts(export))] +/// The search combined id +pub struct SearchCombinedId(i32); + #[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)] #[cfg_attr(feature = "full", derive(DieselNewType, TS))] #[cfg_attr(feature = "full", ts(export))] diff --git a/crates/db_schema/src/schema.rs b/crates/db_schema/src/schema.rs index cb430a3fe..8bd87bfde 100644 --- a/crates/db_schema/src/schema.rs +++ b/crates/db_schema/src/schema.rs @@ -955,6 +955,17 @@ diesel::table! { } } +diesel::table! { + search_combined (id) { + id -> Int4, + published -> Timestamptz, + post_id -> Nullable, + comment_id -> Nullable, + community_id -> Nullable, + person_id -> Nullable, + } +} + diesel::table! { secret (id) { id -> Int4, @@ -1140,6 +1151,10 @@ diesel::joinable!(registration_application -> person (admin_id)); diesel::joinable!(report_combined -> comment_report (comment_report_id)); diesel::joinable!(report_combined -> post_report (post_report_id)); diesel::joinable!(report_combined -> private_message_report (private_message_report_id)); +diesel::joinable!(search_combined -> comment (comment_id)); +diesel::joinable!(search_combined -> community (community_id)); +diesel::joinable!(search_combined -> person (person_id)); +diesel::joinable!(search_combined -> post (post_id)); diesel::joinable!(site -> instance (instance_id)); diesel::joinable!(site_aggregates -> site (site_id)); diesel::joinable!(site_language -> language (language_id)); @@ -1214,6 +1229,7 @@ diesel::allow_tables_to_appear_in_same_query!( registration_application, remote_image, report_combined, + search_combined, secret, sent_activity, site, diff --git a/crates/db_schema/src/source/combined/mod.rs b/crates/db_schema/src/source/combined/mod.rs index 2555ef5be..458fdd519 100644 --- a/crates/db_schema/src/source/combined/mod.rs +++ b/crates/db_schema/src/source/combined/mod.rs @@ -3,3 +3,4 @@ pub mod modlog; pub mod person_content; pub mod person_saved; pub mod report; +pub mod search; diff --git a/migrations/2024-12-12-222846_add_search_combined_table/down.sql b/migrations/2024-12-12-222846_add_search_combined_table/down.sql new file mode 100644 index 000000000..4289e65be --- /dev/null +++ b/migrations/2024-12-12-222846_add_search_combined_table/down.sql @@ -0,0 +1 @@ +DROP TABLE search_combined; diff --git a/migrations/2024-12-12-222846_add_search_combined_table/up.sql b/migrations/2024-12-12-222846_add_search_combined_table/up.sql new file mode 100644 index 000000000..120287e44 --- /dev/null +++ b/migrations/2024-12-12-222846_add_search_combined_table/up.sql @@ -0,0 +1,64 @@ +-- Creates combined tables for +-- Search: (post, comment, community, person) + +CREATE TABLE search_combined ( + id serial PRIMARY KEY, + published timestamptz NOT NULL, + -- TODO Need to figure out all the possible sort types, unified into SearchSortType + -- This is difficult because other than published, there is no unified way to sort them. + -- + -- All have published. + -- post and comment have top and time-limited scores and ranks. + -- persons have post and comment counts, and scores (not time-limited). + -- communities have subscribers, post and comment counts, and active users per X time. + -- + -- I'm thinking just published and score (and use active_monthly users as the community score), is the best way to start. + post_id int UNIQUE REFERENCES post ON UPDATE CASCADE ON DELETE CASCADE, + comment_id int UNIQUE REFERENCES comment ON UPDATE CASCADE ON DELETE CASCADE, + community_id int UNIQUE REFERENCES community ON UPDATE CASCADE ON DELETE CASCADE, + person_id int UNIQUE REFERENCES person ON UPDATE CASCADE ON DELETE CASCADE, + -- Make sure only one of the columns is not null + CHECK (num_nonnulls (post_id, comment_id, community_id, person_id) = 1) +); + +CREATE INDEX idx_search_combined_published ON search_combined (published DESC, id DESC); + +CREATE INDEX idx_search_combined_published_asc ON search_combined (reverse_timestamp_sort (published) DESC, id DESC); + +-- Updating the history +INSERT INTO search_combined (published, post_id, comment_id, community_id, person_id) +SELECT + published, + id, + NULL::int, + NULL::int, + NULL::int +FROM + post +UNION ALL +SELECT + published, + NULL::int, + id, + NULL::int, + NULL::int +FROM + comment +UNION ALL +SELECT + published, + NULL::int, + NULL::int, + id, + NULL::int +FROM + community +UNION ALL +SELECT + published, + NULL::int, + NULL::int, + NULL::int, + id +FROM + person;