-- original code: https://github.com/ericelliott/cuid -- Add the "plv8" extension create extension if not exists "plv8"; -- Add the "pgcrypto" extension create extension if not exists "pgcrypto"; \dx -- Connect a database \c mydb -- initialize CREATE OR REPLACE FUNCTION plv8_init() RETURNS void AS $$ const blockSize = 4; const base = 36; const discreteValues = Math.pow(base, blockSize); let c = 0; function pad(num, size) { const s = '000000000' + num; return s.substring(s.length - size); } function fingerprint() { const padding = 2; const pid = plv8.execute(`select pg_backend_pid() as pid`)[0].pid; const pidWithPadding = pad(pid.toString(36, padding)); const hostname = plv8.execute(`select inet_server_addr() as hostname`)[0].hostname; const length = hostname.length; const hostId = pad( hostname .split('') .reduce((prev, char) => +prev + char.charCodeAt(0), +length + 36) .toString(36) , padding); return pid + hostId; } function getRandomValue() { const lim = Math.pow(2, 32) - 1; const len = 4; const num = plv8.execute(`select ('x' || right(public.gen_random_bytes($1)::text, 8))::bit(32)::int as num`, [len])[0].num; return Math.abs(num / lim); } function randomBlock() { return pad((getRandomValue() * discreteValues << 0).toString(base), blockSize); } function safeCounter() { c = c < discreteValues ? c : 0; c++; return c - 1; } plv8.global = { c, blockSize, base, discreteValues, pad, fingerprint, getRandomValue, randomBlock, safeCounter }; $$ LANGUAGE plv8 STRICT; -- SET plv8.start_proc = 'plv8_init'; -- RESET plv8.start_proc alter database mydb set plv8.start_proc to plv8_init; CREATE OR REPLACE FUNCTION cuid() RETURNS text AS $$ const { base, blockSize, safeCounter, fingerprint, randomBlock, pad } = plv8.global; const letter = 'c'; const timestamp = (new Date().getTime()).toString(base); const counter = pad(safeCounter().toString(base), blockSize); const print = fingerprint(); const random = randomBlock() + randomBlock(); // return `letter: ${letter}, timestamp: ${timestamp}, counter: ${counter}, print: ${print}, random: ${random}`; return letter + timestamp + counter + print + random; $$ LANGUAGE plv8 STRICT;