Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions vlib/orm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ struct Foo {
### Structs

- `[table: 'name']` explicitly sets the name of the table for the struct
- `[comment: 'table_comment']` explicitly sets the comment of the table for the struct
- `[index: 'f1, f2, f3']` explicitly sets fields of the table (`f1`, `f2`, `f3`) as indexed

### Fields

Expand All @@ -36,6 +38,9 @@ struct Foo {
surround `raw_sql` with backticks (\`).

- `[fkey: 'parent_id']` sets foreign key for an field which holds an array
- `[references]` or `[references: 'tablename']` or `[references: 'tablename(field_id)']`
- `[comment: 'field_comment']` set comment
- `[index]` creates index

## Usage
> [!NOTE]
Expand Down
29 changes: 29 additions & 0 deletions vlib/orm/orm.v
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ pub fn orm_table_gen(sql_dialect SQLDialect, table Table, q string, defaults boo
mut primary_typ := 0
mut table_comment := ''
mut field_comments := map[string]string{}
mut index_fields := []string{}

for attr in table.attrs {
match attr.name {
Expand All @@ -479,6 +480,19 @@ pub fn orm_table_gen(sql_dialect SQLDialect, table Table, q string, defaults boo
table_comment = attr.arg.replace('"', '\\"')
}
}
'index' {
if attr.arg != '' && attr.kind == .string {
index_strings := attr.arg.split(',')
for i in index_strings {
x := i.trim_space()
if x.len > 0 && x !in index_fields {
index_fields << x
}
}
} else {
return error("index attribute needs to be in the format [index: 'f1, f2, f3']")
}
}
else {}
}
}
Expand Down Expand Up @@ -568,6 +582,11 @@ pub fn orm_table_gen(sql_dialect SQLDialect, table Table, q string, defaults boo
field_comments[field_name] = field_comment
}
}
'index' {
if field_name !in index_fields {
index_fields << field_name
}
}
else {}
}
}
Expand Down Expand Up @@ -622,6 +641,11 @@ pub fn orm_table_gen(sql_dialect SQLDialect, table Table, q string, defaults boo

fs << unique_fields
str += fs.join(', ')
if index_fields.len > 0 && sql_dialect == .mysql {
str += ', INDEX `idx_${table.name}` (`'
str += index_fields.join('`,`')
str += '`)'
}
str += ')'
if sql_dialect == .mysql && table_comment != '' {
str += " COMMENT = '${table_comment}'"
Expand All @@ -636,6 +660,11 @@ pub fn orm_table_gen(sql_dialect SQLDialect, table Table, q string, defaults boo
str += "\nCOMMENT ON COLUMN \"${table.name}\".\"${f}\" IS '${c}';"
}
}
if (sql_dialect == .pg || sql_dialect == .sqlite) && index_fields.len > 0 {
str += '\nCREATE INDEX "idx_${table.name}" ON "${table.name}" ("'
str += index_fields.join('","')
str += '");'
}
$if trace_orm_create ? {
eprintln('> orm_create table: ${table.name} | query: ${str}')
}
Expand Down
9 changes: 5 additions & 4 deletions vlib/orm/orm_func_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import db.sqlite
import time

@[table: 'sys_users']
@[index: 'name, age']
struct User {
id int @[primary; serial]
name string
id int @[primary; serial]
name string @[index]
age int
role string
status int
role string @[index]
status int @[index]
salary int
title string
score int
Expand Down
7 changes: 4 additions & 3 deletions vlib/orm/orm_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import db.sqlite

const offset_const = 2

@[index: 'name, nr_downloads']
struct Module {
id int @[primary; sql: serial]
name string
id int @[primary; sql: serial]
name string @[index]
nr_downloads int
test_id u64
test_id u64 @[index]
user ?User
created time.Time
}
Expand Down
Loading