Skip to content

Instantly share code, notes, and snippets.

@PatrickChoDev
Last active December 18, 2024 10:52
Show Gist options
  • Save PatrickChoDev/6c386384e933622889bd8324b47c992d to your computer and use it in GitHub Desktop.
Save PatrickChoDev/6c386384e933622889bd8324b47c992d to your computer and use it in GitHub Desktop.
Generating CUID2 with PostgreSQL
CREATE OR REPLACE FUNCTION generate_cuid2(target_length INT DEFAULT 24)
RETURNS TEXT AS $$
DECLARE
timestamp_part TEXT; -- Encoded timestamp in base36
random_part TEXT; -- Random string for uniqueness
random_length INT; -- Length of the random part
characters TEXT := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; -- Alphanumeric characters
result TEXT; -- Final result to return
BEGIN
-- Validate input length
IF target_length < 8 THEN
RAISE EXCEPTION 'Target length must be at least 8 characters';
END IF;
-- Generate the time-based prefix (always 8 characters)
timestamp_part := LPAD(TO_HEX(EXTRACT(EPOCH FROM clock_timestamp())::BIGINT), 8, '0');
-- Calculate the length of the random part
random_length := target_length - LENGTH(timestamp_part);
-- Generate the random part
random_part := (
SELECT STRING_AGG(SUBSTRING(characters, FLOOR(1 + RANDOM() * 62)::INT, 1), '')
FROM generate_series(1, random_length)
);
-- Combine timestamp and random parts
result := LEFT(timestamp_part || random_part, target_length);
RETURN result;
END;
$$ LANGUAGE plpgsql;
select gen_cuid2() cuid, clock_timestamp()-statement_timestamp() time_taken;
CREATE TABLE users (
user_id CHAR(24) PRIMARY KEY DEFAULT generate_cuid2(), -- Generate a 24-character cuid2
username TEXT NOT NULL UNIQUE, -- Username must be unique
email TEXT NOT NULL UNIQUE, -- Email must be unique
password_hash TEXT NOT NULL, -- Securely store password hashes
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Automatically set creation time
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- Automatically set update time
);
CREATE TABLE longer_users (
user_id CHAR(32) PRIMARY KEY DEFAULT generate_cuid2(32), -- Generate a 32-character cuid2
username TEXT NOT NULL UNIQUE, -- Username must be unique
email TEXT NOT NULL UNIQUE, -- Email must be unique
password_hash TEXT NOT NULL, -- Securely store password hashes
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Automatically set creation time
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- Automatically set update time
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment