|
5 | 5 | -- + Defines functions to generate and validate typeids in SQL. |
6 | 6 |
|
7 | 7 | -- Create a `typeid` type. |
8 | | --- Note that the "uuid" field should be a UUID v7. |
9 | 8 | create type "typeid" as ("type" varchar(63), "uuid" uuid); |
10 | 9 |
|
11 | 10 | -- Function that generates a random typeid of the given type. |
@@ -38,47 +37,30 @@ language plpgsql |
38 | 37 | volatile; |
39 | 38 |
|
40 | 39 | -- Function that checks if a typeid is valid, for the given type prefix. |
41 | | --- It also enforces that the UUID is a v7 UUID. |
42 | | --- NOTE: we might want to make the version check optional. |
43 | 40 | create or replace function typeid_check(tid typeid, expected_type text) |
44 | 41 | returns boolean |
45 | 42 | as $$ |
46 | 43 | declare |
47 | 44 | prefix text; |
48 | | - bytes bytea; |
49 | | - ver int; |
50 | 45 | begin |
51 | 46 | prefix = (tid).type; |
52 | | - bytes = uuid_send((tid).uuid); |
53 | | - ver = (get_byte(bytes, 6) >> 4)::bit(4)::int; |
54 | | - -- Check that: |
55 | | - -- + The prefix matches the expected type |
56 | | - -- + The UUID version is 7 OR it's the special "nil" UUID |
57 | | - return prefix = expected_type AND (ver = 7 OR (tid).uuid = '00000000-0000-0000-0000-000000000000'); |
| 47 | + return prefix = expected_type; |
58 | 48 | end |
59 | 49 | $$ |
60 | 50 | language plpgsql |
61 | 51 | immutable; |
62 | 52 |
|
63 | 53 | -- Function that checks if a typeid is valid, for the given type_id in text format and type prefix, returns boolean. |
64 | | --- It also enforces that the UUID is a v7 UUID. |
65 | | -create or replace function typeid_check_text(type_id text, expected_type text) |
| 54 | +create or replace function typeid_check_text(typeid_str text, expected_type text) |
66 | 55 | returns boolean |
67 | 56 | as $$ |
68 | 57 | declare |
69 | 58 | prefix text; |
70 | 59 | tid typeid; |
71 | | - bytes bytea; |
72 | | - ver int; |
73 | 60 | begin |
74 | | - tid = typeid_parse(type_id); |
| 61 | + tid = typeid_parse(typeid_str); |
75 | 62 | prefix = (tid).type; |
76 | | - bytes = uuid_send((tid).uuid); |
77 | | - ver = (get_byte(bytes, 6) >> 4)::bit(4)::int; |
78 | | - -- Check that: |
79 | | - -- + The prefix matches the expected type |
80 | | - -- + The UUID version is 7 OR it's the special "nil" UUID |
81 | | - return prefix = expected_type AND (ver = 7 OR (tid).uuid = '00000000-0000-0000-0000-000000000000'); |
| 63 | + return prefix = expected_type; |
82 | 64 | end |
83 | 65 | $$ |
84 | 66 | language plpgsql |
|
138 | 120 | $$ |
139 | 121 | language plpgsql |
140 | 122 | immutable; |
141 | | - |
142 | | --- Enables direct textual equality checks. This enables direct querying in pSQL without |
143 | | --- having to have clients know about db column internals- e.g. using the users table |
144 | | --- example in example.sql: |
145 | | --- |
146 | | --- Query: |
147 | | --- SELECT * FROM users u WHERE u.id = 'user_01h455vb4pex5vsknk084sn02q' |
148 | | --- |
149 | | --- Result: |
150 | | --- "(user,018962e7-3a6d-7290-b088-5c4e3bdf918c)",Ben Bitdiddle,ben@bitdiddle.com |
151 | | --- |
152 | | --- Note: This also has the nice benefit of playing very well with generators |
153 | | --- such as Hibernate/JPA/JDBC/r2dbc, as you'll be able to do direct equality checks |
154 | | --- in repositories, such as for r2dbc: |
155 | | --- |
156 | | --- @Query(value = "SELECT u.id, u.name, u.email FROM users u WHERE u.id = :id") |
157 | | --- Mono<UserEntity> findByPassedInTypeId(@Param("id") Mono<String> typeId); // user_01h455vb4pex5vsknk084sn02q |
158 | | --- |
159 | | --- Note: This function only has to ever be declared once, and will work for any domains that use |
160 | | --- the original typeid type (e.g. this function gets called when querying for a user_id even though |
161 | | --- we never explicitly override the quality operator for a user_id. |
162 | | -CREATE OR REPLACE FUNCTION compare_type_id_equality(lhs_id typeid, rhs_id VARCHAR) |
163 | | - RETURNS BOOLEAN AS $$ |
164 | | -SELECT lhs_id = typeid_parse(rhs_id); |
165 | | -$$ LANGUAGE SQL IMMUTABLE; |
166 | | - |
167 | | -CREATE OPERATOR = ( |
168 | | - LEFTARG = typeid, |
169 | | - RIGHTARG = VARCHAR, |
170 | | - PROCEDURE = compare_type_id_equality, |
171 | | - COMMUTATOR = =, |
172 | | - NEGATOR = !=, |
173 | | - HASHES, |
174 | | - MERGES |
175 | | - ); |
176 | | - |
0 commit comments