Skip to content

Instantly share code, notes, and snippets.

@tylersmalley
Last active December 16, 2015 23:39
Show Gist options
  • Save tylersmalley/5515235 to your computer and use it in GitHub Desktop.
Save tylersmalley/5515235 to your computer and use it in GitHub Desktop.
Druuid PostgreSQL support: https://github.com/recurly/druuid
CREATE OR REPLACE FUNCTION public.epoch_offset() RETURNS bigint AS $$
BEGIN
RETURN 135702720000; -- 2013-01-01 00:00:00
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION public.druuid(epoch bigint default NULL) RETURNS bigint AS $$
DECLARE
result bigint;
BEGIN
epoch := COALESCE(epoch, (SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 100)));
result := (epoch - epoch_offset()) << 23;
result := result | (FLOOR(RANDOM() * 1e16)::bigint % 8388608);
RETURN result;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION public.druuid_epoch(druuid bigint) RETURNS bigint AS $$
BEGIN
RETURN (druuid >> 23) + epoch_offset();
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION public.druuid_time(druuid bigint) RETURNS timestamp AS $$
DECLARE
ms bigint := druuid_epoch(druuid);
BEGIN
RETURN (SELECT TIMESTAMP 'epoch' + (ms / 1e2) * INTERVAL '1 second');
END;
$$ LANGUAGE plpgsql;
@tylersmalley
Copy link
Author

SELECT epoch_offset();
-- 135702720000
ALTER TABLE users ALTER COLUMN id SET DEFAULT druuid()

You can also pass an epoch in milliseconds as an argument.

SELECT druuid(136762687675)
-- 8891653325149927

And retrieve the epoch/time from the id

SELECT druuid_epoch(8891653325149927)
-- 136762687675

SELECT druuid_time(8891653325149927)
-- 2013-05-04 00:21:16.75

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment