orm: mysql fixes (#14772)
parent
fb5a40d1c8
commit
5df3d8ac75
117
vlib/mysql/orm.v
117
vlib/mysql/orm.v
|
@ -15,6 +15,7 @@ pub fn (db Connection) @select(config orm.SelectConfig, data orm.QueryData, wher
|
||||||
|
|
||||||
mysql_stmt_binder(mut stmt, where)?
|
mysql_stmt_binder(mut stmt, where)?
|
||||||
mysql_stmt_binder(mut stmt, data)?
|
mysql_stmt_binder(mut stmt, data)?
|
||||||
|
|
||||||
if data.data.len > 0 || where.data.len > 0 {
|
if data.data.len > 0 || where.data.len > 0 {
|
||||||
stmt.bind_params()?
|
stmt.bind_params()?
|
||||||
}
|
}
|
||||||
|
@ -24,52 +25,48 @@ pub fn (db Connection) @select(config orm.SelectConfig, data orm.QueryData, wher
|
||||||
metadata := stmt.gen_metadata()
|
metadata := stmt.gen_metadata()
|
||||||
fields := stmt.fetch_fields(metadata)
|
fields := stmt.fetch_fields(metadata)
|
||||||
|
|
||||||
mut dataptr := []Prims{}
|
mut dataptr := []&u8{}
|
||||||
|
|
||||||
for i in 0 .. num_fields {
|
for i in 0 .. num_fields {
|
||||||
f := unsafe { fields[i] }
|
f := unsafe { fields[i] }
|
||||||
match FieldType(f.@type) {
|
match FieldType(f.@type) {
|
||||||
.type_tiny {
|
.type_tiny {
|
||||||
dataptr << u8(0)
|
dataptr << unsafe { malloc(1) }
|
||||||
}
|
}
|
||||||
.type_short {
|
.type_short {
|
||||||
dataptr << u16(0)
|
dataptr << unsafe { malloc(2) }
|
||||||
}
|
}
|
||||||
.type_long {
|
.type_long {
|
||||||
dataptr << u32(0)
|
dataptr << unsafe { malloc(4) }
|
||||||
}
|
}
|
||||||
.type_longlong {
|
.type_longlong {
|
||||||
dataptr << u64(0)
|
dataptr << unsafe { malloc(8) }
|
||||||
}
|
}
|
||||||
.type_float {
|
.type_float {
|
||||||
dataptr << f32(0)
|
dataptr << unsafe { malloc(4) }
|
||||||
}
|
}
|
||||||
.type_double {
|
.type_double {
|
||||||
dataptr << f64(0)
|
dataptr << unsafe { malloc(8) }
|
||||||
}
|
}
|
||||||
.type_string {
|
.type_string, .type_blob {
|
||||||
dataptr << ''
|
dataptr << unsafe { malloc(512) }
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dataptr << u8(0)
|
dataptr << &u8(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mut vptr := []&char{}
|
|
||||||
|
|
||||||
for d in dataptr {
|
|
||||||
vptr << d.get_data_ptr()
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe { dataptr.free() }
|
|
||||||
|
|
||||||
lens := []u32{len: int(num_fields), init: 0}
|
lens := []u32{len: int(num_fields), init: 0}
|
||||||
stmt.bind_res(fields, vptr, lens, num_fields)
|
stmt.bind_res(fields, dataptr, lens, num_fields)
|
||||||
stmt.bind_result_buffer()?
|
stmt.bind_result_buffer()?
|
||||||
stmt.store_result()?
|
stmt.store_result()?
|
||||||
|
|
||||||
mut row := 0
|
mut row := 0
|
||||||
|
mut types := config.types
|
||||||
|
if config.is_count {
|
||||||
|
types = [orm.type_idx['u64']]
|
||||||
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
status = stmt.fetch_stmt()?
|
status = stmt.fetch_stmt()?
|
||||||
|
@ -78,7 +75,8 @@ pub fn (db Connection) @select(config orm.SelectConfig, data orm.QueryData, wher
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
row++
|
row++
|
||||||
data_list := buffer_to_primitive(vptr, config.types)?
|
|
||||||
|
data_list := buffer_to_primitive(dataptr, types)?
|
||||||
ret << data_list
|
ret << data_list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +182,8 @@ fn stmt_binder_match(mut stmt Stmt, data orm.Primitive) {
|
||||||
stmt.bind_text(data)
|
stmt.bind_text(data)
|
||||||
}
|
}
|
||||||
time.Time {
|
time.Time {
|
||||||
stmt.bind_int(&int(data.unix))
|
unix := int(data.unix)
|
||||||
|
stmt_binder_match(mut stmt, unix)
|
||||||
}
|
}
|
||||||
orm.InfixType {
|
orm.InfixType {
|
||||||
stmt_binder_match(mut stmt, data.right)
|
stmt_binder_match(mut stmt, data.right)
|
||||||
|
@ -192,50 +191,50 @@ fn stmt_binder_match(mut stmt Stmt, data orm.Primitive) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn buffer_to_primitive(data_list []&char, types []int) ?[]orm.Primitive {
|
fn buffer_to_primitive(data_list []&u8, types []int) ?[]orm.Primitive {
|
||||||
mut res := []orm.Primitive{}
|
mut res := []orm.Primitive{}
|
||||||
|
|
||||||
for i, data in data_list {
|
for i, data in data_list {
|
||||||
mut primitive := orm.Primitive(0)
|
mut primitive := orm.Primitive(0)
|
||||||
match types[i] {
|
match types[i] {
|
||||||
5 {
|
orm.type_idx['i8'] {
|
||||||
primitive = *(&i8(data))
|
primitive = *(unsafe { &i8(data) })
|
||||||
}
|
}
|
||||||
6 {
|
orm.type_idx['i16'] {
|
||||||
primitive = *(&i16(data))
|
primitive = *(unsafe { &i16(data) })
|
||||||
}
|
}
|
||||||
7, -1 {
|
orm.type_idx['int'], orm.serial {
|
||||||
primitive = *(&int(data))
|
primitive = *(unsafe { &int(data) })
|
||||||
}
|
}
|
||||||
8 {
|
orm.type_idx['i64'] {
|
||||||
primitive = *(&i64(data))
|
primitive = *(unsafe { &i64(data) })
|
||||||
}
|
}
|
||||||
9 {
|
orm.type_idx['byte'] {
|
||||||
primitive = *(&u8(data))
|
primitive = *(unsafe { &u8(data) })
|
||||||
}
|
}
|
||||||
10 {
|
orm.type_idx['u16'] {
|
||||||
primitive = *(&u16(data))
|
primitive = *(unsafe { &u16(data) })
|
||||||
}
|
}
|
||||||
11 {
|
orm.type_idx['u32'] {
|
||||||
primitive = *(&u32(data))
|
primitive = *(unsafe { &u32(data) })
|
||||||
}
|
}
|
||||||
12 {
|
orm.type_idx['u64'] {
|
||||||
primitive = *(&u64(data))
|
primitive = *(unsafe { &u64(data) })
|
||||||
}
|
}
|
||||||
13 {
|
orm.type_idx['f32'] {
|
||||||
primitive = *(&f32(data))
|
primitive = *(unsafe { &f32(data) })
|
||||||
}
|
}
|
||||||
14 {
|
orm.type_idx['f64'] {
|
||||||
primitive = *(&f64(data))
|
primitive = *(unsafe { &f64(data) })
|
||||||
}
|
}
|
||||||
15 {
|
orm.type_idx['bool'] {
|
||||||
primitive = *(&bool(data))
|
primitive = *(unsafe { &bool(data) })
|
||||||
}
|
}
|
||||||
orm.string {
|
orm.string {
|
||||||
primitive = unsafe { cstring_to_vstring(&char(data)) }
|
primitive = unsafe { cstring_to_vstring(&char(data)) }
|
||||||
}
|
}
|
||||||
orm.time {
|
orm.time {
|
||||||
timestamp := *(&int(data))
|
timestamp := *(unsafe { &int(data) })
|
||||||
primitive = time.unix(timestamp)
|
primitive = time.unix(timestamp)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -250,30 +249,33 @@ fn buffer_to_primitive(data_list []&char, types []int) ?[]orm.Primitive {
|
||||||
|
|
||||||
fn mysql_type_from_v(typ int) ?string {
|
fn mysql_type_from_v(typ int) ?string {
|
||||||
str := match typ {
|
str := match typ {
|
||||||
5, 9, 16 {
|
orm.type_idx['i8'], orm.type_idx['byte'] {
|
||||||
'TINYINT'
|
'TINYINT'
|
||||||
}
|
}
|
||||||
6, 10 {
|
orm.type_idx['i16'], orm.type_idx['u16'] {
|
||||||
'SMALLINT'
|
'SMALLINT'
|
||||||
}
|
}
|
||||||
7, 11, orm.time {
|
orm.type_idx['int'], orm.type_idx['u32'], orm.time {
|
||||||
'INT'
|
'INT'
|
||||||
}
|
}
|
||||||
8, 12 {
|
orm.type_idx['i64'], orm.type_idx['u64'] {
|
||||||
'BIGINT'
|
'BIGINT'
|
||||||
}
|
}
|
||||||
13 {
|
orm.type_idx['f32'] {
|
||||||
'FLOAT'
|
'FLOAT'
|
||||||
}
|
}
|
||||||
14 {
|
orm.type_idx['f64'] {
|
||||||
'DOUBLE'
|
'DOUBLE'
|
||||||
}
|
}
|
||||||
orm.string {
|
orm.string {
|
||||||
'TEXT'
|
'TEXT'
|
||||||
}
|
}
|
||||||
-1 {
|
orm.serial {
|
||||||
'SERIAL'
|
'SERIAL'
|
||||||
}
|
}
|
||||||
|
orm.type_idx['bool'] {
|
||||||
|
'BOOLEAN'
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
''
|
''
|
||||||
}
|
}
|
||||||
|
@ -283,14 +285,3 @@ fn mysql_type_from_v(typ int) ?string {
|
||||||
}
|
}
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p Prims) get_data_ptr() &char {
|
|
||||||
return match p {
|
|
||||||
string {
|
|
||||||
p.str
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
&char(&p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -210,14 +210,14 @@ pub fn (mut stmt Stmt) bind(typ int, buffer voidptr, buf_len u32) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut stmt Stmt) bind_res(fields &C.MYSQL_FIELD, dataptr []&char, lens []u32, num_fields int) {
|
pub fn (mut stmt Stmt) bind_res(fields &C.MYSQL_FIELD, dataptr []&u8, lens []u32, num_fields int) {
|
||||||
for i in 0 .. num_fields {
|
for i in 0 .. num_fields {
|
||||||
len := FieldType(unsafe { fields[i].@type }).get_len()
|
len := FieldType(unsafe { fields[i].@type }).get_len()
|
||||||
stmt.res << C.MYSQL_BIND{
|
stmt.res << C.MYSQL_BIND{
|
||||||
buffer_type: unsafe { fields[i].@type }
|
buffer_type: unsafe { fields[i].@type }
|
||||||
buffer: dataptr[i]
|
buffer: dataptr[i]
|
||||||
length: &lens[i]
|
length: &lens[i]
|
||||||
buffer_length: &len
|
buffer_length: len
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ pub const (
|
||||||
]
|
]
|
||||||
string = ast.string_type_idx
|
string = ast.string_type_idx
|
||||||
time = -2
|
time = -2
|
||||||
|
serial = -1
|
||||||
type_idx = {
|
type_idx = {
|
||||||
'i8': ast.i8_type_idx
|
'i8': ast.i8_type_idx
|
||||||
'i16': ast.i16_type_idx
|
'i16': ast.i16_type_idx
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// import os
|
// import os
|
||||||
// import term
|
// import term
|
||||||
import time
|
// import mysql
|
||||||
// import pg
|
// import pg
|
||||||
|
import time
|
||||||
import sqlite
|
import sqlite
|
||||||
|
|
||||||
struct Module {
|
struct Module {
|
||||||
|
@ -33,9 +34,17 @@ struct TestTime {
|
||||||
|
|
||||||
fn test_orm() {
|
fn test_orm() {
|
||||||
db := sqlite.connect(':memory:') or { panic(err) }
|
db := sqlite.connect(':memory:') or { panic(err) }
|
||||||
// db.exec('drop table if exists User')
|
db.exec('drop table if exists User')
|
||||||
|
|
||||||
// db := pg.connect(host: 'localhost', port: 5432, user: 'louis', password: 'abc', dbname: 'orm') or { panic(err) }
|
// db := pg.connect(host: 'localhost', port: 5432, user: 'louis', password: 'abc', dbname: 'orm') or { panic(err) }
|
||||||
|
/*
|
||||||
|
mut db := mysql.Connection{
|
||||||
|
host: '127.0.0.1'
|
||||||
|
username: 'root'
|
||||||
|
password: 'pw'
|
||||||
|
dbname: 'v'
|
||||||
|
}
|
||||||
|
db.connect() or { panic(err) }*/
|
||||||
|
|
||||||
sql db {
|
sql db {
|
||||||
create table Module
|
create table Module
|
||||||
|
@ -268,7 +277,7 @@ fn test_orm() {
|
||||||
assert updated_oldest.age == 31
|
assert updated_oldest.age == 31
|
||||||
|
|
||||||
// Remove this when pg is used
|
// Remove this when pg is used
|
||||||
db.exec('insert into User (name, age) values (NULL, 31)')
|
// db.exec('insert into User (name, age) values (NULL, 31)')
|
||||||
null_user := sql db {
|
null_user := sql db {
|
||||||
select from User where id == 5
|
select from User where id == 5
|
||||||
}
|
}
|
||||||
|
@ -319,6 +328,7 @@ fn test_orm() {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert data.len == 1
|
assert data.len == 1
|
||||||
|
assert tnow.unix == data[0].create.unix
|
||||||
|
|
||||||
mod := Module{}
|
mod := Module{}
|
||||||
|
|
||||||
|
|
|
@ -205,7 +205,7 @@ fn pg_type_from_v(typ int) ?string {
|
||||||
orm.string {
|
orm.string {
|
||||||
'TEXT'
|
'TEXT'
|
||||||
}
|
}
|
||||||
-1 {
|
orm.serial {
|
||||||
'SERIAL'
|
'SERIAL'
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -20,6 +20,7 @@ pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.Qu
|
||||||
mut ret := [][]orm.Primitive{}
|
mut ret := [][]orm.Primitive{}
|
||||||
|
|
||||||
if config.is_count {
|
if config.is_count {
|
||||||
|
eprintln(config)
|
||||||
// 2. Get count of returned values & add it to ret array
|
// 2. Get count of returned values & add it to ret array
|
||||||
step := stmt.step()
|
step := stmt.step()
|
||||||
if step !in [sqlite_row, sqlite_ok, sqlite_done] {
|
if step !in [sqlite_row, sqlite_ok, sqlite_done] {
|
||||||
|
|
|
@ -22,7 +22,7 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type {
|
||||||
return ast.void_type
|
return ast.void_type
|
||||||
}
|
}
|
||||||
info := sym.info as ast.Struct
|
info := sym.info as ast.Struct
|
||||||
fields := c.fetch_and_verify_orm_fields(info, node.table_expr.pos, sym.name)
|
mut fields := c.fetch_and_verify_orm_fields(info, node.table_expr.pos, sym.name)
|
||||||
mut sub_structs := map[int]ast.SqlExpr{}
|
mut sub_structs := map[int]ast.SqlExpr{}
|
||||||
for f in fields.filter((c.table.type_symbols[int(it.typ)].kind == .struct_
|
for f in fields.filter((c.table.type_symbols[int(it.typ)].kind == .struct_
|
||||||
|| (c.table.sym(it.typ).kind == .array
|
|| (c.table.sym(it.typ).kind == .array
|
||||||
|
@ -81,6 +81,13 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type {
|
||||||
|
|
||||||
sub_structs[int(typ)] = n
|
sub_structs[int(typ)] = n
|
||||||
}
|
}
|
||||||
|
if node.is_count {
|
||||||
|
fields = [
|
||||||
|
ast.StructField{
|
||||||
|
typ: ast.int_type
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
node.fields = fields
|
node.fields = fields
|
||||||
node.sub_structs = sub_structs.move()
|
node.sub_structs = sub_structs.move()
|
||||||
if node.has_where {
|
if node.has_where {
|
||||||
|
|
Loading…
Reference in New Issue