-
-
Save jperl/d6835cbc1698771cf8f5c5c0d468948a to your computer and use it in GitHub Desktop.
cuid for PostgreSQL with PL/v8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- original code: https://github.com/ericelliott/cuid | |
| -- Add "plv8" extension | |
| create extension if not exists "plv8"; | |
| \dx | |
| -- Connect a database | |
| \c mydb | |
| -- for initialize | |
| CREATE OR REPLACE FUNCTION plv8_init() RETURNS void AS $$ | |
| pad = function pad(num, size) { | |
| var s = '000000000' + num; | |
| return s.substr(s.length - size); | |
| } | |
| fingerprint = function fingerprint() { | |
| var padding = 2; | |
| var pid = plv8.execute(`select pg_backend_pid() as pid`)[0].pid; | |
| var pidWithPadding = pad(pid.toString(36, padding)); | |
| var hostname = plv8.execute(`select inet_server_addr() as hostname`)[0].hostname; | |
| var length = hostname.length; | |
| var hostId = | |
| pad( | |
| hostname | |
| .split('') | |
| .reduce((prev, char) => +prev + char.charCodeAt(0), +length + 36) | |
| .toString(36) | |
| , padding); | |
| return pid + hostId; | |
| } | |
| getRandomValue = function getRandomValue() { | |
| var lim = Math.pow(2, 32) - 1; | |
| var len = 4; | |
| var 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); | |
| } | |
| c = 0; | |
| blockSize = 4; | |
| base = 36; | |
| discreteValues = Math.pow(base, blockSize); | |
| randomBlock = function randomBlock() { | |
| return pad((getRandomValue() * discreteValues << 0).toString(base), blockSize); | |
| } | |
| safeCounter = function safeCounter() { | |
| c = c < discreteValues ? c : 0; | |
| c++; | |
| return c - 1; | |
| } | |
| $$ LANGUAGE plv8 STRICT; | |
| alter database mydb set plv8.start_proc to plv8_init; | |
| CREATE OR REPLACE FUNCTION plv8_cuid() RETURNS text AS $$ | |
| var letter = 'c'; | |
| var timestamp = (new Date().getTime()).toString(base); | |
| var counter = pad(safeCounter().toString(base), blockSize); | |
| var print = fingerprint(); | |
| var random = randomBlock() + randomBlock(); | |
| return letter + timestamp + counter + print + random; | |
| $$ LANGUAGE plv8 STRICT; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| mydb=# select plv8_cuid(); | |
| plv8_cuid | |
| ---------------------------- | |
| ck2ag1r6h00ln320f2ejrthj1p | |
| (1 row) | |
| mydb=# select plv8_cuid(); | |
| plv8_cuid | |
| ---------------------------- | |
| ck2ag1rkq00lo320f2g3ro0o7o | |
| (1 row) | |
| mydb=# select plv8_cuid(); | |
| plv8_cuid | |
| ---------------------------- | |
| ck2ag1rsg00lp320f2f32ccfi3 | |
| (1 row) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment