Skip to content

Instantly share code, notes, and snippets.

@sylvainv
Last active August 8, 2020 15:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sylvainv/b8cb7f4aebb15df0ff1514cf9e1aac75 to your computer and use it in GitHub Desktop.
Save sylvainv/b8cb7f4aebb15df0ff1514cf9e1aac75 to your computer and use it in GitHub Desktop.
Records timestamps on insert/update helper for PostgreSQL
CREATE OR REPLACE FUNCTION add_timestamps_to_table(_table text, _type text) RETURNS void AS $$
BEGIN
EXECUTE format('ALTER TABLE %I ADD COLUMN IF NOT EXISTS created_at %s', _table, _type);
EXECUTE format('ALTER TABLE %I ADD COLUMN IF NOT EXISTS updated_at %s', _table, _type);
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION set_timestamps_not_null_on_table(_table text) RETURNS void AS $$
BEGIN
EXECUTE format('ALTER TABLE %I ALTER COLUMN created_at SET NOT NULL', _table);
EXECUTE format('ALTER TABLE %I ALTER COLUMN updated_at SET NOT NULL', _table);
END;
$$ LANGUAGE 'plpgsql';
-------------
-- TRIGGER --
-------------
CREATE OR REPLACE FUNCTION record_creation_time() RETURNS TRIGGER AS $$
DECLARE force boolean;
BEGIN
force = false;
if TG_NARGS > 0 then
force = TG_ARGV[0];
end if;
if NEW.created_at is null or force is true then
NEW.created_at = NOW();
end if;
if NEW.updated_at is null or force is true then
NEW.updated_at = NOW();
end if;
return NEW;
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION record_update_time() RETURNS TRIGGER AS $$
DECLARE force boolean;
BEGIN
force = false;
if TG_NARGS > 0 then
force = TG_ARGV[0];
end if;
if NEW.updated_at is null or force is true then
NEW.updated_at = NOW();
end if;
return NEW;
END;
$$ LANGUAGE 'plpgsql';
--------------------
-- CREATE TRIGGER --
--------------------
CREATE OR REPLACE FUNCTION record_timestamps_on_update(_table text, _force boolean = false) RETURNS void AS $$
BEGIN
EXECUTE format('DROP TRIGGER IF EXISTS update_updated_at ON %I', _table);
EXECUTE format(
'CREATE TRIGGER record_update_time BEFORE UPDATE ON %I FOR EACH ROW EXECUTE PROCEDURE record_update_time(%L)',
_table, _force
);
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION record_timestamps_on_create(_table text, _force boolean = false) RETURNS void AS $$
BEGIN
EXECUTE format('DROP TRIGGER IF EXISTS record_creation_time ON %I', _table);
EXECUTE format(
'CREATE TRIGGER record_creation_time BEFORE INSERT ON %I FOR EACH ROW EXECUTE PROCEDURE record_creation_time(%L)',
_table, _force
);
END;
$$ LANGUAGE 'plpgsql';
CREATE OR REPLACE FUNCTION record_timestamps_for_table(_table text, _force boolean = false) RETURNS void AS $$
BEGIN
PERFORM record_timestamps_on_update(_table, _force);
PERFORM record_timestamps_on_create(_table, _force);
END;
$$ LANGUAGE 'plpgsql';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment