Skip to content

Commit aaa23bb

Browse files
authored
orm: update readme with more specifics (#21697)
1 parent 72a3fd6 commit aaa23bb

File tree

1 file changed

+101
-32
lines changed

1 file changed

+101
-32
lines changed

vlib/orm/README.md

Lines changed: 101 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,45 @@
11
# ORM
22

3-
## Null
3+
V has a powerful, concise ORM baked in! Create tables, insert records, manage relationships, all
4+
regardless of the DB driver you decide to use.
45

5-
Use option fields in V structs for fields which can be NULL. Regular,
6-
non-option fields are defied as NOT NULL when creating tables.
6+
## Nullable
7+
8+
For a nullable column, use an option field. If the field is non-option, the column will be defined
9+
with `NOT NULL` at table creation.
10+
11+
```v ignore
12+
struct Foo {
13+
notnull string
14+
nullable ?string
15+
}
16+
```
717

818
## Attributes
919

1020
### Structs
1121

12-
- `[table: 'name']` sets a custom table name
22+
- `[table: 'name']` explicitly sets the name of the table for the struct
1323

1424
### Fields
1525

1626
- `[primary]` sets the field as the primary key
17-
- `[unique]` sets the field as unique
18-
- `[unique: 'foo']` adds the field to a unique group
27+
- `[unique]` gives the field a `UNIQUE` constraint
28+
- `[unique: 'foo']` adds the field to a `UNIQUE` group
1929
- `[skip]` or `[sql: '-']` field will be skipped
2030
- `[sql: type]` where `type` is a V type such as `int` or `f64`
21-
- `[sql: serial]` lets the DB backend choose a column type for a auto-increment field
31+
- `[sql: serial]` lets the DB backend choose a column type for an auto-increment field
2232
- `[sql: 'name']` sets a custom column name for the field
23-
- `[sql_type: 'SQL TYPE']` sets the sql type which is used in sql
24-
- `[default: 'raw_sql]` inserts `raw_sql` verbatim in a "DEFAULT" clause when
25-
create a new table, allowing for values like `CURRENT_TIME`
33+
- `[sql_type: 'SQL TYPE']` explicitly sets the type in SQL
34+
- `[default: 'raw_sql']` inserts `raw_sql` verbatim in a "DEFAULT" clause when
35+
creating a new table, allowing for SQL functions like `CURRENT_TIME`. For raw strings,
36+
surround `raw_sql` with backticks (`).
2637
- `[fkey: 'parent_id']` sets foreign key for an field which holds an array
2738

2839
## Usage
2940

41+
Here are a couple example structs showing most of the features outlined above.
42+
3043
```v ignore
3144
import time
3245
@@ -47,23 +60,55 @@ struct Child {
4760
}
4861
```
4962

50-
### Create
63+
To use the ORM, there is a special interface that lets you use the structs and V itself in queries.
64+
This interface takes the database instance as an argument.
5165

5266
```v ignore
67+
import db.sqlite
68+
69+
db := sqlite.connect(':memory:')!
70+
5371
sql db {
54-
create table Foo
72+
// query; see below
5573
}!
5674
```
5775

58-
### Drop
76+
When you need to reference the table, simply pass the struct itself.
5977

6078
```v ignore
79+
import models.Foo
80+
81+
struct Bar {
82+
id int @[primary; sql: serial]
83+
}
84+
6185
sql db {
62-
drop table Foo
86+
create table models.Foo
87+
create table Bar
6388
}!
6489
```
6590

66-
### Insert
91+
### Create & Drop Tables
92+
93+
You can create and drop tables by passing the struct to `create table` and `drop table`.
94+
95+
```v ignore
96+
import models.Foo
97+
98+
struct Bar {
99+
id int @[primary; sql: serial]
100+
}
101+
102+
sql db {
103+
create table models.Foo
104+
drop table Bar
105+
}!
106+
```
107+
108+
### Insert Records
109+
110+
To insert a record, create a struct and pass the variable to the query. Again, reference the struct
111+
as the table.
67112

68113
```v ignore
69114
foo := Foo{
@@ -86,52 +131,76 @@ foo_id := sql db {
86131
}!
87132
```
88133

89-
If the `id` field is marked as `serial` and `primary`, the insert expression
134+
If the `id` field is marked as `sql: serial` and `primary`, the insert expression
90135
returns the database ID of the newly added object. Getting an ID of a newly
91136
added DB row is often useful.
92137

93138
When inserting, `[sql: serial]` fields, and fields with a `[default: 'raw_sql']`
94-
attribute are not sent to the database when the value being sent is the default
139+
attribute, are not sent to the database when the value being sent is the default
95140
for the V struct field (e.g., 0 int, or an empty string). This allows the
96141
database to insert default values for auto-increment fields and where you have
97142
specified a default.
98143

144+
### Select
99145

100-
### Update
146+
You can select rows from the database by passing the struct as the table, and
147+
use V syntax and functions for expressions. Selecting returns an array of the
148+
results.
101149

102150
```v ignore
103-
sql db {
104-
update Foo set updated_at = time.now() where name == 'abc' && updated_at is none
151+
result := sql db {
152+
select from Foo where id == 1
105153
}!
106-
```
107154
108-
Note that `is none` and `!is none` can be used to select for NULL fields.
155+
foo := result.first()
156+
```
109157

110-
### Delete
111158
```v ignore
112-
sql db {
113-
delete from Foo where id > 10
159+
result := sql db {
160+
select from Foo where id > 1 && name != 'lasanha' limit 5
114161
}!
115162
```
116163

117-
### Select
118164
```v ignore
119165
result := sql db {
120-
select from Foo where id == 1
166+
select from Foo where id > 1 order by id
121167
}!
122168
```
169+
170+
171+
### Update
172+
173+
You can update fields in a row using V syntax and functions. Again, pass the struct
174+
as the table.
175+
123176
```v ignore
124-
result := sql db {
125-
select from Foo where id > 1 && name != 'lasanha' limit 5
177+
sql db {
178+
update Foo set updated_at = time.now() where name == 'abc' && updated_at is none
126179
}!
127180
```
181+
182+
Note that `is none` and `!is none` can be used to select for NULL fields.
183+
184+
### Delete
185+
186+
You can delete rows using V syntax and functions. Again, pass the struct
187+
as the table.
188+
128189
```v ignore
129-
result := sql db {
130-
select from Foo where id > 1 order by id
190+
sql db {
191+
delete from Foo where id > 10
131192
}!
132193
```
133194

134-
### Example
195+
### time.Time Fields
196+
197+
It's definitely useful to cast a field as `time.Time` so you can use V's built-in time functions;
198+
however, this is handled a bit differently than expected in the ORM. `time.Time` fields are
199+
created as integer columns in the database. Because of this, the usual time functions
200+
(`current_timestamp`, `NOW()`, etc) in SQL do not work as defaults.
201+
202+
## Example
203+
135204
```v ignore
136205
import db.pg
137206

0 commit comments

Comments
 (0)