Created
June 24, 2012 13:37
-
-
Save singingwolfboy/2983260 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE FUNCTION apply_hunks(content text[], page_id int, | |
min_revision int, max_revision int, reverse boolean DEFAULT FALSE) | |
RETURNS text[] as $$ | |
declare | |
hunk record; | |
revision int := null; | |
offset int := 0; | |
start int; | |
length int; | |
content_line text; | |
hunk_line text; | |
hunk_content_line text; | |
marker char(1); | |
applied_hunk text[]; | |
content_length int; | |
begin | |
FOR hunk in SELECT * | |
FROM page_diff_hunk AS hunk | |
WHERE hunk.page_id = page_id | |
AND hunk.revision >= min_revision | |
AND hunk.revision < max_revision | |
ORDER BY hunk.revision DESC, hunk.start ASC | |
LOOP | |
IF revision != hunk.revision THEN | |
revision := hunk.revision; | |
-- reset offset | |
offset := 0; | |
END IF; | |
start := hunk.start + "offset"; | |
content_line := content[start]; | |
FOREACH hunk_line IN ARRAY string_to_array(hunk.content, E'\n') LOOP | |
marker = left(hunk_line, 1); | |
hunk_content_line = substr(hunk_line, 2); | |
IF (marker = ' ') or (marker = '+' and not reverse) or (marker = '-' and reverse) THEN | |
applied_hunk := array_append(applied_hunk, hunk_content_line); | |
END IF; | |
END LOOP; | |
-- replace content array | |
content_length := array_length(content, 1); | |
content := content[1:hunk.start] + applied_hunk + | |
content[start:content_length]; | |
END LOOP; | |
RETURN content; | |
end; | |
$$ language plpgsql | |
STABLE STRICT; | |
CREATE FUNCTION apply_hunks_cursor(content text[], hunks refcursor, | |
reverse boolean DEFAULT FALSE) returns text[] AS $$ | |
declare | |
hunk record; | |
revision int := null; | |
offset int := 0; | |
start int; | |
length int; | |
content_line text; | |
hunk_line text; | |
hunk_content_line text; | |
marker char(1); | |
applied_hunk text[]; | |
content_length int; | |
begin | |
FOR hunk IN hunks LOOP | |
IF revision != hunk.revision THEN | |
revision := hunk.revision; | |
-- reset offset | |
offset := 0; | |
END IF; | |
start := hunk.start + "offset"; | |
content_line := content[start]; | |
FOREACH hunk_line IN ARRAY string_to_array(hunk.content, E'\n') LOOP | |
marker = left(hunk_line, 1); | |
hunk_content_line = substr(hunk_line, 2); | |
IF (marker = ' ') or (marker = '+' and not reverse) or (marker = '-' and reverse) THEN | |
applied_hunk := array_append(applied_hunk, hunk_content_line); | |
END IF; | |
END LOOP; | |
-- replace content array | |
content_length := array_length(content, 1); | |
content := content[1:hunk.start] + applied_hunk + | |
content[start:content_length]; | |
END LOOP; | |
RETURN content; | |
end; | |
$$ language plpgsql | |
STABLE STRICT; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment