@@ -25,52 +25,94 @@ for development and testing, but you do **not** need to use Supabase for this
2525implementation to work – simply use the Postgres instance of your choice.
2626
2727## Usage
28-
2928Once you've installed the TypeID types and functions in your Postgres instance,
30- you can use it as follows.
29+ you have two options on how to encode TypeIDs in your database.
30+
31+ ### 1. Text-based encoding
32+ This encoding is more inefficient than the alternative, but it's very straight-forward
33+ to understand, it's easy to debug by simply inspecting the contents of your tables, and
34+ it works well with other tools you might be using to inspect your database.
3135
32- To define a new type of typeid with a specific prefix use the `typeid\_
36+ To use it:
37+ + Declare your ` id ` column using the ` text ` type.
38+ + Use the ` typeid_generate_text ` function to generate new default values.
39+ + Use the ` typeid_check_text ` to enforce all strings in the column are valid typeids.
40+
41+ Example:
3342
3443``` sql
3544-- Define a `users` table that uses `user_id` as its primary key.
36- -- We use the `typeid_generate ` function to randomly generate a new typeid of the
45+ -- We use the `typeid_generate_text ` function to randomly generate a new typeid of the
3746-- correct type for each user.
47+ -- We also recommend adding the check constraint to the column
3848CREATE TABLE users (
39- " id" user_id not null default typeid_generate (' user' ),
49+ " id" text not null default typeid_generate_text (' user' ) CHECK (typeid_check_text(id, ' user ' ) ),
4050 " name" text ,
4151 " email" text
4252);
4353
44- -- Now we can insert new uses and have the `id` column automatically generated.
54+ -- Now we can insert new users and have the `id` column automatically generated.
4555INSERT INTO users (" name" , " email" ) VALUES (' Alice P. Hacker' , ' alice@hacker.net' );
56+ SELECT id FROM users;
57+ -- Result:
58+ -- "user_01hfs6amkdfem8sb6b1xmg7tq7"
59+
60+ -- Insert a user with a specific typeid that might have been generated elsewhere:
61+ INSERT INTO users (" id" , " name" , " email" )
62+ VALUES (' user_01h455vb4pex5vsknk084sn02q' , ' Ben Bitdiddle' , ' ben@bitdiddle.com' );
63+
64+ -- To retrieve the ids as encoded strings, just use the column:
65+ SELECT id AS id, " name" , " email" FROM users;
66+
67+ -- You can also use filter in a WHERE clause to filter by typeid:
68+ SELECT typeid_print(id) AS id, " name" , " email" FROM users
69+ WHERE id = ' user_01h455vb4pex5vsknk084sn02q' ;
4670```
4771
48- Or
72+ ### 2. UUID-based encoding using compound types
73+ In this approach, we internally encode typeids as a ` (prefix, uuid) ` tuple. The
74+ sql files in this library provide a predefined ` typeid ` type to represent
75+ said tuples.
76+
77+ The advantage of this approach is that it is a more efficient encoding because we
78+ store the uuid portion of the typeid using the native ` uuid ` type.
4979
50- You can use the typeid_generate_text function to generate a new typeid as a string, and not use the typeid type
80+ The disadvanage is that it is harder to work with and debug.
81+
82+ If performance is a primary concern of yours, also consider using the native
83+ [ postgres extension] ( https://github.com/blitss/typeid-postgres ) for typeid,
84+ which exposes typeids as a "built-in" type.
85+
86+ To define a new typeid using this encoding, you can use the ` typeid_check ` function:
87+ ``` sql
88+ -- Define a `user_id` type, which is a typeid with type prefix "user".
89+ -- Using `user_id` throughout our schema, gives us type safety by guaranteeing
90+ -- that the type prefix is always "user".
91+ CREATE DOMAIN user_id AS typeid CHECK (typeid_check(value, ' user' ));
92+ ```
93+
94+ You can now use the newly defined type in your tables. The ` typeid_generate ` function
95+ makes it possible to automatically a new random typeid for each row:
5196
5297``` sql
5398-- Define a `users` table that uses `user_id` as its primary key.
54- -- We use the `typeid_generate_text ` function to randomly generate a new typeid of the
99+ -- We use the `typeid_generate ` function to randomly generate a new typeid of the
55100-- correct type for each user.
56- -- You will need to manually add the check constraint to the column
57101CREATE TABLE users (
58- " id" text not null default typeid_generate_text (' user' ) CHECK (typeid_check_text(id, ' user ' ) ),
102+ " id" user_id not null default typeid_generate (' user' ),
59103 " name" text ,
60104 " email" text
61105);
62106
63- -- Now we can insert new uses and have the `id` column automatically generated.
107+ -- Now we can insert new users and have the `id` column automatically generated.
64108INSERT INTO users (" name" , " email" ) VALUES (' Alice P. Hacker' , ' alice@hacker.net' );
65- SELECT id FROM users;
66- -- Result:
67- -- "user_01hfs6amkdfem8sb6b1xmg7tq7"
68109```
110+ #### Querying
111+ To make it easy to query typeid tuples using the standard string representation, we
112+ provide two convenience functions: ` typeid_parse ` and ` typeid_print ` , which convert
113+ to and from the standard string representation.
69114
70- Note that the database internally encodes typeids as a ` (prefix, uuid) ` tuple. Because
71- this is different than the standard string representation of typeids in other libraries,
72- we provide a ` typeid_parse ` and a ` typeid_print ` function that can be used to write
73- queries with the standard string representation of typeids:
115+ Example:
74116
75117``` sql
76118-- Insert a user with a specific typeid that might have been generated elsewhere:
@@ -85,22 +127,7 @@ SELECT typeid_print(id) AS id, "name", "email" FROM users
85127WHERE id = typeid_parse(' user_01h455vb4pex5vsknk084sn02q' );
86128```
87129
88- or for the text variant
89-
90- ``` sql
91- -- Insert a user with a specific typeid that might have been generated elsewhere:
92- INSERT INTO users (" id" , " name" , " email" )
93- VALUES (' user_01h455vb4pex5vsknk084sn02q' , ' Ben Bitdiddle' , ' ben@bitdiddle.com' );
94-
95- -- To retrieve the ids as encoded strings, just use the column:
96- SELECT id AS id, " name" , " email" FROM users;
97-
98- -- You can also use filter in a WHERE clause to filter by typeid:
99- SELECT typeid_print(id) AS id, " name" , " email" FROM users
100- WHERE id = ' user_01h455vb4pex5vsknk084sn02q' ;
101- ```
102-
103- ## (Optional) Operator overload
130+ #### (Optional) Operator overload
104131
105132If you'd like to be able to do the following:
106133
@@ -112,7 +139,10 @@ SELECT * FROM users u WHERE u.id = 'user_01h455vb4pex5vsknk084sn02q';
112139-- "(user,018962e7-3a6d-7290-b088-5c4e3bdf918c)",Ben Bitdiddle,ben@bitdiddle.com
113140```
114141
115- Then you can add in [ the operator overload function for typeids] ( https://github.com/search?q=repo%3Ajetify-com%2Ftypeid-sql%20compare_type_id_equality&type=code ) :
142+ Then you can add in [ the operator overload functions for typeid] ( https://github.com/jetify-com/typeid-sql/blob/main/sql/04_operator.sql ) .
143+
144+ Some users have reported issues with the above operator when using Rails and ActiveRecord – we
145+ recommend removing ` COMMUTATOR ` from the operator definition if you encounter issues.
116146
117147## Future work (contributions welcome)
118148
0 commit comments