mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
orm: default attribute (#15221)
This commit is contained in:

committed by
GitHub

parent
c976a691ad
commit
e5e750d533
@ -15,6 +15,7 @@
|
||||
- `[sql: type]` where `type` is a V type such as `int` or `f64`, or special type `serial`
|
||||
- `[sql: 'name']` sets a custom column name for the field
|
||||
- `[sql_type: 'SQL TYPE']` sets the sql type which is used in sql
|
||||
- `[default: 'sql defaults']` sets the default value or function when create a new table
|
||||
|
||||
## Usage
|
||||
|
||||
@ -90,3 +91,53 @@ result := sql db {
|
||||
select from Foo where id > 1 order by id
|
||||
}
|
||||
```
|
||||
|
||||
### Example
|
||||
```v ignore
|
||||
import pg
|
||||
|
||||
struct Member {
|
||||
id string [default: 'gen_random_uuid()'; primary; sql_type: 'uuid']
|
||||
name string
|
||||
created_at string [default: 'CURRENT_TIMESTAMP'; sql_type: 'TIMESTAMP']
|
||||
}
|
||||
|
||||
fn main() {
|
||||
db := pg.connect(pg.Config{
|
||||
host: 'localhost'
|
||||
port: 5432
|
||||
user: 'user'
|
||||
password: 'password'
|
||||
dbname: 'dbname'
|
||||
}) or {
|
||||
println(err)
|
||||
return
|
||||
}
|
||||
|
||||
defer {
|
||||
db.close()
|
||||
}
|
||||
|
||||
sql db {
|
||||
create table Member
|
||||
}
|
||||
|
||||
new_member := Member{
|
||||
name: 'John Doe'
|
||||
}
|
||||
|
||||
sql db {
|
||||
insert new_member into Member
|
||||
}
|
||||
|
||||
selected_member := sql db {
|
||||
select from Member where name == 'John Doe' limit 1
|
||||
}
|
||||
|
||||
sql db {
|
||||
update Member set name = 'Hitalo' where id == selected_member.id
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
```
|
@ -182,27 +182,42 @@ pub interface Connection {
|
||||
// num - Stmt uses nums at prepared statements (? or ?1)
|
||||
// qm - Character for prepared statment, qm because of quotation mark like in sqlite
|
||||
// start_pos - When num is true, it's the start position of the counter
|
||||
pub fn orm_stmt_gen(table string, q string, kind StmtKind, num bool, qm string, start_pos int, data QueryData, where QueryData) string {
|
||||
pub fn orm_stmt_gen(table string, q string, kind StmtKind, num bool, qm string, start_pos int, data QueryData, where QueryData) (string, QueryData) {
|
||||
mut str := ''
|
||||
|
||||
mut c := start_pos
|
||||
mut data_fields := []string{}
|
||||
mut data_data := []Primitive{}
|
||||
|
||||
match kind {
|
||||
.insert {
|
||||
mut values := []string{}
|
||||
mut select_fields := []string{}
|
||||
|
||||
for _ in 0 .. data.fields.len {
|
||||
// loop over the length of data.field and generate ?0, ?1 or just ? based on the $num qmeter for value placeholders
|
||||
if num {
|
||||
values << '$qm$c'
|
||||
c++
|
||||
} else {
|
||||
values << '$qm'
|
||||
for i in 0 .. data.fields.len {
|
||||
if data.data.len > 0 {
|
||||
match data.data[i].type_name() {
|
||||
'string' {
|
||||
if (data.data[i] as string).len == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
'time.Time' {
|
||||
if (data.data[i] as time.Time).unix == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
else {}
|
||||
}
|
||||
data_data << data.data[i]
|
||||
}
|
||||
select_fields << '$q${data.fields[i]}$q'
|
||||
values << factory_insert_qm_value(num, qm, c)
|
||||
data_fields << data.fields[i]
|
||||
c++
|
||||
}
|
||||
|
||||
str += 'INSERT INTO $q$table$q ('
|
||||
str += data.fields.map('$q$it$q').join(', ')
|
||||
str += select_fields.join(', ')
|
||||
str += ') VALUES ('
|
||||
str += values.join(', ')
|
||||
str += ')'
|
||||
@ -262,7 +277,13 @@ pub fn orm_stmt_gen(table string, q string, kind StmtKind, num bool, qm string,
|
||||
}
|
||||
}
|
||||
str += ';'
|
||||
return str
|
||||
return str, QueryData{
|
||||
fields: data_fields
|
||||
data: data_data
|
||||
types: data.types
|
||||
kinds: data.kinds
|
||||
is_and: data.is_and
|
||||
}
|
||||
}
|
||||
|
||||
// Generates an sql select stmt, from universal parameter
|
||||
@ -357,6 +378,7 @@ pub fn orm_table_gen(table string, q string, defaults bool, def_unique_len int,
|
||||
if field.is_arr {
|
||||
continue
|
||||
}
|
||||
mut default_val := field.default_val
|
||||
mut no_null := false
|
||||
mut is_unique := false
|
||||
mut is_skip := false
|
||||
@ -397,6 +419,14 @@ pub fn orm_table_gen(table string, q string, defaults bool, def_unique_len int,
|
||||
}
|
||||
ctyp = attr.arg
|
||||
}
|
||||
'default' {
|
||||
if attr.kind != .string {
|
||||
return error("default attribute need be string. Try [default: '$attr.arg'] instead of [default: $attr.arg]")
|
||||
}
|
||||
if default_val == '' {
|
||||
default_val = attr.arg
|
||||
}
|
||||
}
|
||||
/*'fkey' {
|
||||
if attr.arg != '' {
|
||||
if attr.kind == .string {
|
||||
@ -416,8 +446,8 @@ pub fn orm_table_gen(table string, q string, defaults bool, def_unique_len int,
|
||||
return error('Unknown type ($field.typ) for field $field.name in struct $table')
|
||||
}
|
||||
stmt = '$q$field_name$q $ctyp'
|
||||
if defaults && field.default_val != '' {
|
||||
stmt += ' DEFAULT $field.default_val'
|
||||
if defaults && default_val != '' {
|
||||
stmt += ' DEFAULT $default_val'
|
||||
}
|
||||
if no_null {
|
||||
stmt += ' NOT NULL'
|
||||
@ -543,3 +573,11 @@ pub fn time_to_primitive(b time.Time) Primitive {
|
||||
pub fn infix_to_primitive(b InfixType) Primitive {
|
||||
return Primitive(b)
|
||||
}
|
||||
|
||||
fn factory_insert_qm_value(num bool, qm string, c int) string {
|
||||
if num {
|
||||
return '$qm$c'
|
||||
} else {
|
||||
return '$qm'
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import orm
|
||||
import v.ast
|
||||
|
||||
fn test_orm_stmt_gen_update() {
|
||||
query := orm.orm_stmt_gen('Test', "'", .update, true, '?', 0, orm.QueryData{
|
||||
query, _ := orm.orm_stmt_gen('Test', "'", .update, true, '?', 0, orm.QueryData{
|
||||
fields: ['test', 'a']
|
||||
data: []
|
||||
types: []
|
||||
@ -17,7 +17,7 @@ fn test_orm_stmt_gen_update() {
|
||||
}
|
||||
|
||||
fn test_orm_stmt_gen_insert() {
|
||||
query := orm.orm_stmt_gen('Test', "'", .insert, true, '?', 0, orm.QueryData{
|
||||
query, _ := orm.orm_stmt_gen('Test', "'", .insert, true, '?', 0, orm.QueryData{
|
||||
fields: ['test', 'a']
|
||||
data: []
|
||||
types: []
|
||||
@ -27,7 +27,7 @@ fn test_orm_stmt_gen_insert() {
|
||||
}
|
||||
|
||||
fn test_orm_stmt_gen_delete() {
|
||||
query := orm.orm_stmt_gen('Test', "'", .delete, true, '?', 0, orm.QueryData{
|
||||
query, _ := orm.orm_stmt_gen('Test', "'", .delete, true, '?', 0, orm.QueryData{
|
||||
fields: ['test', 'a']
|
||||
data: []
|
||||
types: []
|
||||
|
Reference in New Issue
Block a user