1
1
# ORM
2
2
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.
4
5
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
+ ```
7
17
8
18
## Attributes
9
19
10
20
### Structs
11
21
12
- - ` [table: 'name'] ` sets a custom table name
22
+ - ` [table: 'name'] ` explicitly sets the name of the table for the struct
13
23
14
24
### Fields
15
25
16
26
- ` [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
19
29
- ` [skip] ` or ` [sql: '-'] ` field will be skipped
20
30
- ` [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
22
32
- ` [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 (`).
26
37
- ` [fkey: 'parent_id'] ` sets foreign key for an field which holds an array
27
38
28
39
## Usage
29
40
41
+ Here are a couple example structs showing most of the features outlined above.
42
+
30
43
``` v ignore
31
44
import time
32
45
@@ -47,23 +60,55 @@ struct Child {
47
60
}
48
61
```
49
62
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.
51
65
52
66
``` v ignore
67
+ import db.sqlite
68
+
69
+ db := sqlite.connect(':memory:')!
70
+
53
71
sql db {
54
- create table Foo
72
+ // query; see below
55
73
}!
56
74
```
57
75
58
- ### Drop
76
+ When you need to reference the table, simply pass the struct itself.
59
77
60
78
``` v ignore
79
+ import models.Foo
80
+
81
+ struct Bar {
82
+ id int @[primary; sql: serial]
83
+ }
84
+
61
85
sql db {
62
- drop table Foo
86
+ create table models.Foo
87
+ create table Bar
63
88
}!
64
89
```
65
90
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.
67
112
68
113
``` v ignore
69
114
foo := Foo{
@@ -86,52 +131,76 @@ foo_id := sql db {
86
131
}!
87
132
```
88
133
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
90
135
returns the database ID of the newly added object. Getting an ID of a newly
91
136
added DB row is often useful.
92
137
93
138
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
95
140
for the V struct field (e.g., 0 int, or an empty string). This allows the
96
141
database to insert default values for auto-increment fields and where you have
97
142
specified a default.
98
143
144
+ ### Select
99
145
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.
101
149
102
150
``` 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
105
153
}!
106
- ```
107
154
108
- Note that ` is none ` and ` !is none ` can be used to select for NULL fields.
155
+ foo := result.first()
156
+ ```
109
157
110
- ### Delete
111
158
``` 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
114
161
}!
115
162
```
116
163
117
- ### Select
118
164
``` v ignore
119
165
result := sql db {
120
- select from Foo where id == 1
166
+ select from Foo where id > 1 order by id
121
167
}!
122
168
```
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
+
123
176
``` 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
126
179
}!
127
180
```
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
+
128
189
``` 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
131
192
}!
132
193
```
133
194
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
+
135
204
``` v ignore
136
205
import db.pg
137
206
0 commit comments