mirror of
https://example.com
synced 2024-11-23 10:46:38 +09:00
53 lines
1.3 KiB
JavaScript
53 lines
1.3 KiB
JavaScript
|
export class noteRepliesFunction1658656633972 {
|
||
|
name = "noteRepliesFunction1658656633972";
|
||
|
|
||
|
async up(queryRunner) {
|
||
|
await queryRunner.query(`
|
||
|
CREATE OR REPLACE FUNCTION note_replies(start_id varchar, max_depth integer, max_breadth integer) RETURNS TABLE (id VARCHAR) AS
|
||
|
$$
|
||
|
SELECT DISTINCT id FROM (
|
||
|
WITH RECURSIVE tree (id, ancestors, depth) AS (
|
||
|
SELECT start_id, '{}'::VARCHAR[], 0
|
||
|
UNION
|
||
|
SELECT
|
||
|
note.id,
|
||
|
CASE
|
||
|
WHEN note."replyId" = tree.id THEN tree.ancestors || note."replyId"
|
||
|
ELSE tree.ancestors || note."renoteId"
|
||
|
END,
|
||
|
depth + 1
|
||
|
FROM note, tree
|
||
|
WHERE (
|
||
|
note."replyId" = tree.id
|
||
|
OR
|
||
|
(
|
||
|
-- get renotes but not pure renotes
|
||
|
note."renoteId" = tree.id
|
||
|
AND
|
||
|
(
|
||
|
note.text IS NOT NULL
|
||
|
OR
|
||
|
CARDINALITY(note."fileIds") != 0
|
||
|
OR
|
||
|
note."hasPoll" = TRUE
|
||
|
)
|
||
|
)
|
||
|
) AND depth < max_depth
|
||
|
)
|
||
|
SELECT
|
||
|
id,
|
||
|
-- apply the limit per node
|
||
|
row_number() OVER (PARTITION BY ancestors[array_upper(ancestors, 1)]) AS nth_child
|
||
|
FROM tree
|
||
|
WHERE depth > 0
|
||
|
) AS recursive WHERE nth_child < max_breadth
|
||
|
$$
|
||
|
LANGUAGE SQL
|
||
|
`);
|
||
|
}
|
||
|
|
||
|
async down(queryRunner) {
|
||
|
await queryRunner.query(`DROP FUNCTION note_replies`);
|
||
|
}
|
||
|
}
|