Skip to content

Instantly share code, notes, and snippets.

@singingwolfboy
Created June 24, 2012 13:37
Show Gist options
  • Save singingwolfboy/2983260 to your computer and use it in GitHub Desktop.
Save singingwolfboy/2983260 to your computer and use it in GitHub Desktop.
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