mirror of
https://github.com/vlang/v.git
synced 2025-08-03 17:57:59 -04:00
parent
87f92b1f66
commit
b1ab54bb1d
@ -448,6 +448,7 @@ pub fn (stmt &StmtHandle) execute(params []string) ![]Row {
|
||||
buffer: param.str
|
||||
buffer_length: u32(param.len)
|
||||
length: 0
|
||||
is_null: 0
|
||||
}
|
||||
bind_params << bind
|
||||
}
|
||||
@ -470,6 +471,7 @@ pub fn (stmt &StmtHandle) execute(params []string) ![]Row {
|
||||
}
|
||||
num_cols := C.mysql_num_fields(query_metadata)
|
||||
mut length := []u32{len: num_cols}
|
||||
mut is_null := []bool{len: num_cols}
|
||||
|
||||
mut binds := []C.MYSQL_BIND{}
|
||||
for i in 0 .. num_cols {
|
||||
@ -478,6 +480,7 @@ pub fn (stmt &StmtHandle) execute(params []string) ![]Row {
|
||||
buffer: 0
|
||||
buffer_length: 0
|
||||
length: unsafe { &length[i] }
|
||||
is_null: unsafe { &is_null[i] }
|
||||
}
|
||||
binds << bind
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ mut:
|
||||
created_at time.Time @[sql_type: 'DATETIME']
|
||||
updated_at string @[sql_type: 'DATETIME']
|
||||
deleted_at time.Time
|
||||
null_date ?time.Time @[sql_type: 'DATETIME']
|
||||
}
|
||||
|
||||
struct TestDefaultAttribute {
|
||||
@ -179,11 +180,26 @@ fn test_mysql_orm() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
model := TestTimeType{
|
||||
model1 := TestTimeType{
|
||||
username: 'hitalo'
|
||||
created_at: today
|
||||
updated_at: today.str()
|
||||
deleted_at: today
|
||||
// null_date is null
|
||||
}
|
||||
model2 := TestTimeType{
|
||||
username: 'tom'
|
||||
created_at: today
|
||||
updated_at: today.str()
|
||||
deleted_at: today
|
||||
null_date: today
|
||||
}
|
||||
model3 := TestTimeType{
|
||||
username: 'kitty'
|
||||
created_at: today
|
||||
updated_at: today.str()
|
||||
deleted_at: today
|
||||
// null_date is null
|
||||
}
|
||||
|
||||
sql db {
|
||||
@ -191,21 +207,41 @@ fn test_mysql_orm() {
|
||||
}!
|
||||
|
||||
sql db {
|
||||
insert model into TestTimeType
|
||||
insert model1 into TestTimeType
|
||||
insert model2 into TestTimeType
|
||||
insert model3 into TestTimeType
|
||||
}!
|
||||
|
||||
results := sql db {
|
||||
select from TestTimeType where username == 'hitalo'
|
||||
select from TestTimeType
|
||||
}!
|
||||
|
||||
sql db {
|
||||
drop table TestTimeType
|
||||
}!
|
||||
|
||||
assert results[0].created_at == model.created_at
|
||||
assert results[0].username == model.username
|
||||
assert results[0].updated_at == model.updated_at
|
||||
assert results[0].deleted_at == model.deleted_at
|
||||
assert results[0].created_at == model1.created_at
|
||||
assert results[0].username == model1.username
|
||||
assert results[0].updated_at == model1.updated_at
|
||||
assert results[0].deleted_at == model1.deleted_at
|
||||
assert results[0].null_date == none
|
||||
|
||||
assert results[1].created_at == model2.created_at
|
||||
assert results[1].username == model2.username
|
||||
assert results[1].updated_at == model2.updated_at
|
||||
assert results[1].deleted_at == model2.deleted_at
|
||||
if x := results[1].null_date {
|
||||
// should not by `none`/`NULL`
|
||||
assert x == model2.deleted_at
|
||||
} else {
|
||||
assert false
|
||||
}
|
||||
|
||||
assert results[2].created_at == model3.created_at
|
||||
assert results[2].username == model3.username
|
||||
assert results[2].updated_at == model3.updated_at
|
||||
assert results[2].deleted_at == model3.deleted_at
|
||||
assert results[2].null_date == none
|
||||
|
||||
/** test default attribute
|
||||
*/
|
||||
|
@ -53,8 +53,9 @@ pub fn (db DB) select(config orm.SelectConfig, data orm.QueryData, where orm.Que
|
||||
}
|
||||
}
|
||||
|
||||
lengths := []u32{len: int(num_fields), init: 0}
|
||||
stmt.bind_res(fields, data_pointers, lengths, num_fields)
|
||||
mut lengths := []u32{len: int(num_fields), init: 0}
|
||||
mut is_null := []bool{len: int(num_fields)}
|
||||
stmt.bind_res(fields, data_pointers, lengths, is_null, num_fields)
|
||||
|
||||
mut types := config.types.clone()
|
||||
mut field_types := []FieldType{}
|
||||
@ -112,7 +113,7 @@ pub fn (db DB) select(config orm.SelectConfig, data orm.QueryData, where orm.Que
|
||||
stmt.fetch_column(bind, index)!
|
||||
}
|
||||
|
||||
result << data_pointers_to_primitives(data_pointers, types, field_types)!
|
||||
result << data_pointers_to_primitives(is_null, data_pointers, types, field_types)!
|
||||
}
|
||||
|
||||
stmt.close()!
|
||||
@ -251,71 +252,70 @@ fn stmt_bind_primitive(mut stmt Stmt, data orm.Primitive) {
|
||||
|
||||
// data_pointers_to_primitives returns an array of `Primitive`
|
||||
// cast from `data_pointers` using `types`.
|
||||
fn data_pointers_to_primitives(data_pointers []&u8, types []int, field_types []FieldType) ![]orm.Primitive {
|
||||
fn data_pointers_to_primitives(is_null []bool, data_pointers []&u8, types []int, field_types []FieldType) ![]orm.Primitive {
|
||||
mut result := []orm.Primitive{}
|
||||
|
||||
for i, data in data_pointers {
|
||||
mut primitive := orm.Primitive(0)
|
||||
match types[i] {
|
||||
orm.type_idx['i8'] {
|
||||
primitive = *(unsafe { &i8(data) })
|
||||
}
|
||||
orm.type_idx['i16'] {
|
||||
primitive = *(unsafe { &i16(data) })
|
||||
}
|
||||
orm.type_idx['int'], orm.serial {
|
||||
primitive = *(unsafe { &int(data) })
|
||||
}
|
||||
orm.type_idx['i64'] {
|
||||
primitive = *(unsafe { &i64(data) })
|
||||
}
|
||||
orm.type_idx['u8'] {
|
||||
primitive = *(unsafe { &u8(data) })
|
||||
}
|
||||
orm.type_idx['u16'] {
|
||||
primitive = *(unsafe { &u16(data) })
|
||||
}
|
||||
orm.type_idx['u32'] {
|
||||
primitive = *(unsafe { &u32(data) })
|
||||
}
|
||||
orm.type_idx['u64'] {
|
||||
primitive = *(unsafe { &u64(data) })
|
||||
}
|
||||
orm.type_idx['f32'] {
|
||||
primitive = *(unsafe { &f32(data) })
|
||||
}
|
||||
orm.type_idx['f64'] {
|
||||
primitive = *(unsafe { &f64(data) })
|
||||
}
|
||||
orm.type_idx['bool'] {
|
||||
primitive = *(unsafe { &bool(data) })
|
||||
}
|
||||
orm.type_string {
|
||||
primitive = unsafe { cstring_to_vstring(&char(data)) }
|
||||
}
|
||||
orm.time_ {
|
||||
match field_types[i] {
|
||||
.type_long {
|
||||
timestamp := *(unsafe { &int(data) })
|
||||
primitive = time.unix(timestamp)
|
||||
}
|
||||
.type_datetime, .type_timestamp {
|
||||
string_time := unsafe { cstring_to_vstring(&char(data)) }
|
||||
if string_time == '' {
|
||||
primitive = orm.Null{}
|
||||
} else {
|
||||
primitive = time.parse(string_time)!
|
||||
if !is_null[i] {
|
||||
match types[i] {
|
||||
orm.type_idx['i8'] {
|
||||
primitive = *(unsafe { &i8(data) })
|
||||
}
|
||||
orm.type_idx['i16'] {
|
||||
primitive = *(unsafe { &i16(data) })
|
||||
}
|
||||
orm.type_idx['int'], orm.serial {
|
||||
primitive = *(unsafe { &int(data) })
|
||||
}
|
||||
orm.type_idx['i64'] {
|
||||
primitive = *(unsafe { &i64(data) })
|
||||
}
|
||||
orm.type_idx['u8'] {
|
||||
primitive = *(unsafe { &u8(data) })
|
||||
}
|
||||
orm.type_idx['u16'] {
|
||||
primitive = *(unsafe { &u16(data) })
|
||||
}
|
||||
orm.type_idx['u32'] {
|
||||
primitive = *(unsafe { &u32(data) })
|
||||
}
|
||||
orm.type_idx['u64'] {
|
||||
primitive = *(unsafe { &u64(data) })
|
||||
}
|
||||
orm.type_idx['f32'] {
|
||||
primitive = *(unsafe { &f32(data) })
|
||||
}
|
||||
orm.type_idx['f64'] {
|
||||
primitive = *(unsafe { &f64(data) })
|
||||
}
|
||||
orm.type_idx['bool'] {
|
||||
primitive = *(unsafe { &bool(data) })
|
||||
}
|
||||
orm.type_string {
|
||||
primitive = unsafe { cstring_to_vstring(&char(data)) }
|
||||
}
|
||||
orm.time_ {
|
||||
match field_types[i] {
|
||||
.type_long {
|
||||
timestamp := *(unsafe { &int(data) })
|
||||
primitive = time.unix(timestamp)
|
||||
}
|
||||
.type_datetime, .type_timestamp {
|
||||
primitive = time.parse(unsafe { cstring_to_vstring(&char(data)) })!
|
||||
}
|
||||
else {}
|
||||
}
|
||||
else {}
|
||||
}
|
||||
orm.enum_ {
|
||||
primitive = *(unsafe { &i64(data) })
|
||||
}
|
||||
else {
|
||||
return error('Unknown type ${types[i]}')
|
||||
}
|
||||
}
|
||||
orm.enum_ {
|
||||
primitive = *(unsafe { &i64(data) })
|
||||
}
|
||||
else {
|
||||
return error('Unknown type ${types[i]}')
|
||||
}
|
||||
} else {
|
||||
primitive = orm.Null{}
|
||||
}
|
||||
result << primitive
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ mut:
|
||||
buffer voidptr
|
||||
buffer_length u32
|
||||
length &u32
|
||||
is_null &bool
|
||||
}
|
||||
|
||||
const mysql_type_decimal = C.MYSQL_TYPE_DECIMAL
|
||||
@ -250,6 +251,7 @@ pub fn (mut stmt Stmt) bind_null() {
|
||||
stmt.binds << C.MYSQL_BIND{
|
||||
buffer_type: mysql_type_null
|
||||
length: 0
|
||||
is_null: 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,16 +263,18 @@ pub fn (mut stmt Stmt) bind(typ int, buffer voidptr, buf_len u32) {
|
||||
buffer: buffer
|
||||
buffer_length: buf_len
|
||||
length: 0
|
||||
is_null: 0
|
||||
}
|
||||
}
|
||||
|
||||
// bind_res will store one result in the statement `stmt`
|
||||
pub fn (mut stmt Stmt) bind_res(fields &C.MYSQL_FIELD, dataptr []&u8, lengths []u32, num_fields int) {
|
||||
pub fn (mut stmt Stmt) bind_res(fields &C.MYSQL_FIELD, dataptr []&u8, lengths []u32, is_null []bool, num_fields int) {
|
||||
for i in 0 .. num_fields {
|
||||
stmt.res << C.MYSQL_BIND{
|
||||
buffer_type: unsafe { fields[i].type }
|
||||
buffer: dataptr[i]
|
||||
length: &lengths[i]
|
||||
is_null: &is_null[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user