mirror of
https://github.com/vlang/v.git
synced 2025-09-09 15:27:05 -04:00
orm: update readme with more specifics (#21697)
This commit is contained in:
parent
72a3fd6f02
commit
aaa23bb058
@ -1,32 +1,45 @@
|
||||
# ORM
|
||||
|
||||
## Null
|
||||
V has a powerful, concise ORM baked in! Create tables, insert records, manage relationships, all
|
||||
regardless of the DB driver you decide to use.
|
||||
|
||||
Use option fields in V structs for fields which can be NULL. Regular,
|
||||
non-option fields are defied as NOT NULL when creating tables.
|
||||
## Nullable
|
||||
|
||||
For a nullable column, use an option field. If the field is non-option, the column will be defined
|
||||
with `NOT NULL` at table creation.
|
||||
|
||||
```v ignore
|
||||
struct Foo {
|
||||
notnull string
|
||||
nullable ?string
|
||||
}
|
||||
```
|
||||
|
||||
## Attributes
|
||||
|
||||
### Structs
|
||||
|
||||
- `[table: 'name']` sets a custom table name
|
||||
- `[table: 'name']` explicitly sets the name of the table for the struct
|
||||
|
||||
### Fields
|
||||
|
||||
- `[primary]` sets the field as the primary key
|
||||
- `[unique]` sets the field as unique
|
||||
- `[unique: 'foo']` adds the field to a unique group
|
||||
- `[unique]` gives the field a `UNIQUE` constraint
|
||||
- `[unique: 'foo']` adds the field to a `UNIQUE` group
|
||||
- `[skip]` or `[sql: '-']` field will be skipped
|
||||
- `[sql: type]` where `type` is a V type such as `int` or `f64`
|
||||
- `[sql: serial]` lets the DB backend choose a column type for a auto-increment field
|
||||
- `[sql: serial]` lets the DB backend choose a column type for an auto-increment field
|
||||
- `[sql: 'name']` sets a custom column name for the field
|
||||
- `[sql_type: 'SQL TYPE']` sets the sql type which is used in sql
|
||||
- `[default: 'raw_sql]` inserts `raw_sql` verbatim in a "DEFAULT" clause when
|
||||
create a new table, allowing for values like `CURRENT_TIME`
|
||||
- `[sql_type: 'SQL TYPE']` explicitly sets the type in SQL
|
||||
- `[default: 'raw_sql']` inserts `raw_sql` verbatim in a "DEFAULT" clause when
|
||||
creating a new table, allowing for SQL functions like `CURRENT_TIME`. For raw strings,
|
||||
surround `raw_sql` with backticks (`).
|
||||
- `[fkey: 'parent_id']` sets foreign key for an field which holds an array
|
||||
|
||||
## Usage
|
||||
|
||||
Here are a couple example structs showing most of the features outlined above.
|
||||
|
||||
```v ignore
|
||||
import time
|
||||
|
||||
@ -47,23 +60,55 @@ struct Child {
|
||||
}
|
||||
```
|
||||
|
||||
### Create
|
||||
To use the ORM, there is a special interface that lets you use the structs and V itself in queries.
|
||||
This interface takes the database instance as an argument.
|
||||
|
||||
```v ignore
|
||||
import db.sqlite
|
||||
|
||||
db := sqlite.connect(':memory:')!
|
||||
|
||||
sql db {
|
||||
create table Foo
|
||||
// query; see below
|
||||
}!
|
||||
```
|
||||
|
||||
### Drop
|
||||
When you need to reference the table, simply pass the struct itself.
|
||||
|
||||
```v ignore
|
||||
import models.Foo
|
||||
|
||||
struct Bar {
|
||||
id int @[primary; sql: serial]
|
||||
}
|
||||
|
||||
sql db {
|
||||
drop table Foo
|
||||
create table models.Foo
|
||||
create table Bar
|
||||
}!
|
||||
```
|
||||
|
||||
### Insert
|
||||
### Create & Drop Tables
|
||||
|
||||
You can create and drop tables by passing the struct to `create table` and `drop table`.
|
||||
|
||||
```v ignore
|
||||
import models.Foo
|
||||
|
||||
struct Bar {
|
||||
id int @[primary; sql: serial]
|
||||
}
|
||||
|
||||
sql db {
|
||||
create table models.Foo
|
||||
drop table Bar
|
||||
}!
|
||||
```
|
||||
|
||||
### Insert Records
|
||||
|
||||
To insert a record, create a struct and pass the variable to the query. Again, reference the struct
|
||||
as the table.
|
||||
|
||||
```v ignore
|
||||
foo := Foo{
|
||||
@ -86,19 +131,48 @@ foo_id := sql db {
|
||||
}!
|
||||
```
|
||||
|
||||
If the `id` field is marked as `serial` and `primary`, the insert expression
|
||||
If the `id` field is marked as `sql: serial` and `primary`, the insert expression
|
||||
returns the database ID of the newly added object. Getting an ID of a newly
|
||||
added DB row is often useful.
|
||||
|
||||
When inserting, `[sql: serial]` fields, and fields with a `[default: 'raw_sql']`
|
||||
attribute are not sent to the database when the value being sent is the default
|
||||
attribute, are not sent to the database when the value being sent is the default
|
||||
for the V struct field (e.g., 0 int, or an empty string). This allows the
|
||||
database to insert default values for auto-increment fields and where you have
|
||||
specified a default.
|
||||
|
||||
### Select
|
||||
|
||||
You can select rows from the database by passing the struct as the table, and
|
||||
use V syntax and functions for expressions. Selecting returns an array of the
|
||||
results.
|
||||
|
||||
```v ignore
|
||||
result := sql db {
|
||||
select from Foo where id == 1
|
||||
}!
|
||||
|
||||
foo := result.first()
|
||||
```
|
||||
|
||||
```v ignore
|
||||
result := sql db {
|
||||
select from Foo where id > 1 && name != 'lasanha' limit 5
|
||||
}!
|
||||
```
|
||||
|
||||
```v ignore
|
||||
result := sql db {
|
||||
select from Foo where id > 1 order by id
|
||||
}!
|
||||
```
|
||||
|
||||
|
||||
### Update
|
||||
|
||||
You can update fields in a row using V syntax and functions. Again, pass the struct
|
||||
as the table.
|
||||
|
||||
```v ignore
|
||||
sql db {
|
||||
update Foo set updated_at = time.now() where name == 'abc' && updated_at is none
|
||||
@ -108,30 +182,25 @@ sql db {
|
||||
Note that `is none` and `!is none` can be used to select for NULL fields.
|
||||
|
||||
### Delete
|
||||
|
||||
You can delete rows using V syntax and functions. Again, pass the struct
|
||||
as the table.
|
||||
|
||||
```v ignore
|
||||
sql db {
|
||||
delete from Foo where id > 10
|
||||
}!
|
||||
```
|
||||
|
||||
### Select
|
||||
```v ignore
|
||||
result := sql db {
|
||||
select from Foo where id == 1
|
||||
}!
|
||||
```
|
||||
```v ignore
|
||||
result := sql db {
|
||||
select from Foo where id > 1 && name != 'lasanha' limit 5
|
||||
}!
|
||||
```
|
||||
```v ignore
|
||||
result := sql db {
|
||||
select from Foo where id > 1 order by id
|
||||
}!
|
||||
```
|
||||
### time.Time Fields
|
||||
|
||||
It's definitely useful to cast a field as `time.Time` so you can use V's built-in time functions;
|
||||
however, this is handled a bit differently than expected in the ORM. `time.Time` fields are
|
||||
created as integer columns in the database. Because of this, the usual time functions
|
||||
(`current_timestamp`, `NOW()`, etc) in SQL do not work as defaults.
|
||||
|
||||
## Example
|
||||
|
||||
### Example
|
||||
```v ignore
|
||||
import db.pg
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user