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
@@ -31,17 +31,18 @@ pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.Qu
|
||||
// sql stmt
|
||||
|
||||
pub fn (db DB) insert(table string, data orm.QueryData) ? {
|
||||
query := orm.orm_stmt_gen(table, '"', .insert, true, '$', 1, data, orm.QueryData{})
|
||||
pg_stmt_worker(db, query, data, orm.QueryData{})?
|
||||
query, converted_data := orm.orm_stmt_gen(table, '"', .insert, true, '$', 1, data,
|
||||
orm.QueryData{})
|
||||
pg_stmt_worker(db, query, converted_data, orm.QueryData{})?
|
||||
}
|
||||
|
||||
pub fn (db DB) update(table string, data orm.QueryData, where orm.QueryData) ? {
|
||||
query := orm.orm_stmt_gen(table, '"', .update, true, '$', 1, data, where)
|
||||
query, _ := orm.orm_stmt_gen(table, '"', .update, true, '$', 1, data, where)
|
||||
pg_stmt_worker(db, query, data, where)?
|
||||
}
|
||||
|
||||
pub fn (db DB) delete(table string, where orm.QueryData) ? {
|
||||
query := orm.orm_stmt_gen(table, '"', .delete, true, '$', 1, orm.QueryData{}, where)
|
||||
query, _ := orm.orm_stmt_gen(table, '"', .delete, true, '$', 1, orm.QueryData{}, where)
|
||||
pg_stmt_worker(db, query, orm.QueryData{}, where)?
|
||||
}
|
||||
|
||||
@@ -163,18 +164,20 @@ fn pg_stmt_match(mut types []u32, mut vals []&char, mut lens []int, mut formats
|
||||
formats << 1
|
||||
}
|
||||
string {
|
||||
types << u32(Oid.t_text)
|
||||
// If paramTypes is NULL, or any particular element in the array is zero,
|
||||
// the server infers a data type for the parameter symbol in the same way
|
||||
// it would do for an untyped literal string.
|
||||
types << &u8(0)
|
||||
vals << data.str
|
||||
lens << data.len
|
||||
formats << 0
|
||||
}
|
||||
time.Time {
|
||||
types << u32(Oid.t_int4)
|
||||
unix := int(data.unix)
|
||||
num := conv.htn32(unsafe { &u32(&unix) })
|
||||
vals << &char(&num)
|
||||
lens << int(sizeof(u32))
|
||||
formats << 1
|
||||
datetime := ((d as time.Time).format_ss() as string)
|
||||
types << &u8(0)
|
||||
vals << datetime.str
|
||||
lens << datetime.len
|
||||
formats << 0
|
||||
}
|
||||
orm.InfixType {
|
||||
pg_stmt_match(mut types, mut vals, mut lens, mut formats, data.right)
|
||||
@@ -190,9 +193,12 @@ fn pg_type_from_v(typ int) ?string {
|
||||
orm.type_idx['bool'] {
|
||||
'BOOLEAN'
|
||||
}
|
||||
orm.type_idx['int'], orm.type_idx['u32'], orm.time {
|
||||
orm.type_idx['int'], orm.type_idx['u32'] {
|
||||
'INT'
|
||||
}
|
||||
orm.time {
|
||||
'TIMESTAMP'
|
||||
}
|
||||
orm.type_idx['i64'], orm.type_idx['u64'] {
|
||||
'BIGINT'
|
||||
}
|
||||
|
||||
@@ -2,39 +2,89 @@ module main
|
||||
|
||||
import orm
|
||||
import pg
|
||||
import v.ast
|
||||
import time
|
||||
|
||||
struct TestCustomSqlType {
|
||||
id int [primary; sql: serial]
|
||||
custom string [sql_type: 'TEXT']
|
||||
custom1 string [sql_type: 'VARCHAR(191)']
|
||||
custom2 string [sql_type: 'TIMESTAMP']
|
||||
custom3 string [sql_type: 'uuid']
|
||||
}
|
||||
|
||||
struct TestCustomWrongSqlType {
|
||||
id int [primary; sql: serial]
|
||||
custom string
|
||||
custom1 string [sql_type: 'VARCHAR']
|
||||
custom2 string [sql_type: 'money']
|
||||
custom3 string [sql_type: 'xml']
|
||||
}
|
||||
|
||||
struct TestTimeType {
|
||||
mut:
|
||||
id int [primary; sql: serial]
|
||||
username string
|
||||
created_at time.Time [sql_type: 'TIMESTAMP']
|
||||
updated_at string [sql_type: 'TIMESTAMP']
|
||||
deleted_at time.Time
|
||||
}
|
||||
|
||||
struct TestDefaultAtribute {
|
||||
id string [default: 'gen_random_uuid()'; primary; sql_type: 'uuid']
|
||||
name string
|
||||
created_at string [default: 'CURRENT_TIMESTAMP'; sql_type: 'TIMESTAMP']
|
||||
}
|
||||
|
||||
fn test_pg_orm() {
|
||||
mut db := pg.connect(
|
||||
host: 'localhost'
|
||||
user: 'postgres'
|
||||
password: ''
|
||||
password: 'password'
|
||||
dbname: 'postgres'
|
||||
) or { panic(err) }
|
||||
|
||||
defer {
|
||||
db.close()
|
||||
}
|
||||
|
||||
db.create('Test', [
|
||||
orm.TableField{
|
||||
name: 'id'
|
||||
typ: 7
|
||||
typ: ast.string_type_idx
|
||||
is_time: false
|
||||
default_val: ''
|
||||
is_arr: false
|
||||
attrs: [
|
||||
StructAttribute{
|
||||
name: 'primary'
|
||||
has_arg: false
|
||||
arg: ''
|
||||
kind: .plain
|
||||
},
|
||||
StructAttribute{
|
||||
name: 'sql'
|
||||
has_arg: true
|
||||
kind: .plain
|
||||
arg: 'serial'
|
||||
kind: .plain
|
||||
},
|
||||
]
|
||||
},
|
||||
orm.TableField{
|
||||
name: 'name'
|
||||
typ: 18
|
||||
typ: ast.string_type_idx
|
||||
is_time: false
|
||||
default_val: ''
|
||||
is_arr: false
|
||||
attrs: []
|
||||
},
|
||||
orm.TableField{
|
||||
name: 'age'
|
||||
typ: 7
|
||||
typ: ast.i64_type_idx
|
||||
is_time: false
|
||||
default_val: ''
|
||||
is_arr: false
|
||||
attrs: []
|
||||
},
|
||||
]) or { panic(err) }
|
||||
|
||||
@@ -45,15 +95,22 @@ fn test_pg_orm() {
|
||||
|
||||
res := db.@select(orm.SelectConfig{
|
||||
table: 'Test'
|
||||
is_count: false
|
||||
has_where: true
|
||||
has_order: false
|
||||
order: ''
|
||||
order_type: .asc
|
||||
has_limit: false
|
||||
primary: 'id'
|
||||
has_offset: false
|
||||
fields: ['id', 'name', 'age']
|
||||
types: [7, 18, 8]
|
||||
types: [ast.int_type_idx, ast.string_type_idx, ast.i64_type_idx]
|
||||
}, orm.QueryData{}, orm.QueryData{
|
||||
fields: ['name']
|
||||
data: [orm.Primitive('Louis'), i64(101)]
|
||||
types: [18]
|
||||
fields: ['name', 'age']
|
||||
data: [orm.Primitive('Louis'), orm.Primitive(101)]
|
||||
types: []
|
||||
kinds: [.eq, .eq]
|
||||
is_and: [true]
|
||||
kinds: [.eq]
|
||||
}) or { panic(err) }
|
||||
|
||||
id := res[0][0]
|
||||
@@ -74,4 +131,97 @@ fn test_pg_orm() {
|
||||
if age is i64 {
|
||||
assert age == 101
|
||||
}
|
||||
|
||||
/** test orm sql type
|
||||
* - verify if all type create by attribute sql_type has created
|
||||
*/
|
||||
|
||||
sql db {
|
||||
create table TestCustomSqlType
|
||||
}
|
||||
|
||||
mut result_custom_sql := db.exec("
|
||||
SELECT DATA_TYPE
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_NAME = 'TestCustomSqlType'
|
||||
ORDER BY ORDINAL_POSITION
|
||||
") or {
|
||||
println(err)
|
||||
panic(err)
|
||||
}
|
||||
mut information_schema_data_types_results := []string{}
|
||||
information_schema_custom_sql := ['integer', 'text', 'character varying',
|
||||
'timestamp without time zone', 'uuid']
|
||||
for data_type in result_custom_sql {
|
||||
information_schema_data_types_results << data_type.vals[0]
|
||||
}
|
||||
|
||||
sql db {
|
||||
drop table TestCustomSqlType
|
||||
}
|
||||
|
||||
assert information_schema_data_types_results == information_schema_custom_sql
|
||||
|
||||
/** test_orm_time_type
|
||||
* - test time.Time v type with sql_type: 'TIMESTAMP'
|
||||
* - test string v type with sql_type: 'TIMESTAMP'
|
||||
* - test time.Time v type without
|
||||
*/
|
||||
today := time.parse('2022-07-16 15:13:27') or {
|
||||
println(err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
model := TestTimeType{
|
||||
username: 'hitalo'
|
||||
created_at: today
|
||||
updated_at: today.str()
|
||||
deleted_at: today
|
||||
}
|
||||
|
||||
sql db {
|
||||
create table TestTimeType
|
||||
}
|
||||
|
||||
sql db {
|
||||
insert model into TestTimeType
|
||||
}
|
||||
|
||||
results := sql db {
|
||||
select from TestTimeType where username == 'hitalo'
|
||||
}
|
||||
|
||||
sql db {
|
||||
drop table TestTimeType
|
||||
}
|
||||
|
||||
assert results[0].username == model.username
|
||||
assert results[0].created_at == model.created_at
|
||||
assert results[0].updated_at == model.updated_at
|
||||
assert results[0].deleted_at == model.deleted_at
|
||||
|
||||
/** test default attribute
|
||||
*/
|
||||
sql db {
|
||||
create table TestDefaultAtribute
|
||||
}
|
||||
|
||||
mut result_defaults := db.exec("
|
||||
SELECT column_default
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_NAME = 'TestDefaultAtribute'
|
||||
ORDER BY ORDINAL_POSITION
|
||||
") or {
|
||||
println(err)
|
||||
panic(err)
|
||||
}
|
||||
mut information_schema_defaults_results := []string{}
|
||||
|
||||
for defaults in result_defaults {
|
||||
information_schema_defaults_results << defaults.vals[0]
|
||||
}
|
||||
sql db {
|
||||
drop table TestDefaultAtribute
|
||||
}
|
||||
assert ['gen_random_uuid()', '', 'CURRENT_TIMESTAMP'] == information_schema_defaults_results
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user