Skip to content

Commit 3755f4b

Browse files
committed
WIP: docs for usertypes feature.
1 parent 6a8befc commit 3755f4b

4 files changed

Lines changed: 184 additions & 1 deletion

File tree

doc/Language/MissingFeatures.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ work on this project [a long time](https://www.youtube.com/watch?v=izQB2-Kmiic):
3636
* Interpreted in-memory implementation of each DB backend, for easy unit testing
3737
* Linq-ish query builder using the type provider's database model
3838
* Statically typed (w/ schema) JSON/XML access
39-
* Custom data types (e.g. Postgres range types)
4039

4140
## In my nightmares
4241

doc/Language/UserTypes/README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# UserTypes
2+
3+
The UserTypes feature allows you to bring custom .NET data types into RZSQL by pointing the type provider at your own assemblies.
4+
5+
This allows you to:
6+
7+
1. Model your domain better, getting columns typed as `EmailAddress` instead of `string`, `UserId` instead of `Guid`, and so on.
8+
2. Make query result row types implement your interfaces. All your queries against the `User` table can return rows implementing an `IUser` interface you define, so you can write consumer code that works on all of them.
9+
3. Remap built-in types to other storage formats. For example, RZSQL's default handling for DateTime in SQLite is to store an ISO8601 string. If you prefer to store it as an integer Unix time, you can do that with a UserType mapping.
10+
4. Store and retrieve data from backend-specific column types RZSQL doesn't natively support, like Postgres `point` or TSQL `geography`.
11+
12+
## The layout
13+
14+
This is how a solution with UserTypes might look:
15+
16+
![](SolutionLayout.gv.svg)
17+
18+
The user types you wish to use MUST be in a separate assembly from your SQL queries, and must build first.
19+
20+
The type provider cannot "see" types defined in the same assembly it's trying to compile. They don't exist yet!
21+
22+
Referencing Rezoom.SQL.Annotations is optional. This is a lightweight package that only defines attribute classes.
23+
Those attributes give you more control over how your custom-mapped UserTypes are translated to SQL.
24+
25+
## Mapping your own primitive types
26+
27+
STUB
28+
29+
## Mapping externally owned primitive types
30+
31+
STUB
32+
33+
## Row interfaces
34+
35+
STUB
36+
37+
## Mapping to vendor-specific database column types
38+
39+
STUB
40+
41+
## Annotation attributes reference
42+
43+
STUB
44+
45+
## Pitfalls to know about
46+
47+
STUB
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// dot -Tsvg -O SolutionLayout.gv
2+
digraph "Solution Layout" {
3+
rankdir=BT
4+
node[shape=plaintext,fontname=Consolas]
5+
6+
rzsql[label=<
7+
<table border="3" cellborder="1" cellspacing="0" cellpadding="14" bgcolor="lightblue">
8+
<tr><td cellpadding="2">NuGet</td></tr>
9+
<tr><td><b>Rezoom.SQL.Provider</b></td></tr>
10+
</table>
11+
>]
12+
13+
annot[label=<
14+
<table border="3" cellborder="1" cellspacing="0" cellpadding="14" bgcolor="lightblue">
15+
<tr><td cellpadding="2">NuGet</td></tr>
16+
<tr><td><b>Rezoom.SQL.Annotations</b></td></tr>
17+
</table>
18+
>]
19+
20+
{ rank=same; rzsql; annot; }
21+
22+
utl[label=<
23+
<table border="3" cellborder="1" cellspacing="0" cellpadding="14">
24+
<tr><td><b>YourProject.UserTypes.fsproj</b></td></tr>
25+
<tr><td align="left">type IUser = abstract member Id : UserId...</td></tr>
26+
<tr><td align="left">type UserId = UserId of int</td></tr>
27+
<tr><td align="left">[&lt;SQLTypeLength(254)&gt;]<br align="left"/>type EmailAddress = EmailAddress of string</td></tr>
28+
<tr><td align="left">type System.TimeOnly with member this.ToPrimitive() = this.ToString(&quot;o&quot;)...</td></tr>
29+
</table>
30+
>]
31+
32+
tpu[label=<
33+
<table border="3" cellborder="1" cellspacing="0" cellpadding="14">
34+
<tr><td colspan="2"><b>YourProject.SQLQueries.fsproj</b></td></tr>
35+
<tr><td>rzsql.json</td><td align="left">{ &quot;UserTypes&quot;: [&quot;YourProject.UserTypes&quot;] }</td></tr>
36+
<tr><td>V1.model.sql</td><td align="left">create table Users(Id UserId primary key, Email EmailAddress, ...)</td></tr>
37+
<tr><td rowspan="3">Query.fs</td><td align="left">type MyQuery = SQL&lt;&quot;select&lt;IUser&gt; * from Users where Id = @id&quot;&gt;</td></tr>
38+
<tr><td align="left">let rows = MyQuery.Command(id = UserId 123).Execute(connection)</td></tr>
39+
<tr><td align="left">let user = rows.[0] :&gt; IUser</td></tr>
40+
41+
</table>
42+
>]
43+
44+
tpu -> utl
45+
tpu -> rzsql
46+
utl -> annot
47+
}
Lines changed: 90 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)