orm: allow variables like q.nr_orders in queries too.

pull/1688/head
Delyan Angelov 2019-08-20 18:05:56 +03:00 committed by Alexander Medvednikov
parent caa6eacf39
commit 1ddc9dc604
3 changed files with 25 additions and 8 deletions

View File

@ -85,6 +85,7 @@ mut:
is_sql bool is_sql bool
sql_i int // $1 $2 $3 sql_i int // $1 $2 $3
sql_params []string // ("select * from users where id = $1", ***"100"***) sql_params []string // ("select * from users where id = $1", ***"100"***)
sql_types []string // int, string and so on; see sql_params
} }
const ( const (
@ -1400,8 +1401,10 @@ fn (p mut Parser) bterm() string {
p.gen('$' + p.sql_i.str()) p.gen('$' + p.sql_i.str())
p.cgen.start_cut() p.cgen.start_cut()
p.check_types(p.expression(), typ) p.check_types(p.expression(), typ)
p.sql_params << p.cgen.cut() sql_param := p.cgen.cut()
//println('sql params = "$p.sql_params"') p.sql_params << sql_param
p.sql_types << typ
//println('*** sql type: $typ | param: $sql_param')
} else { } else {
p.check_types(p.expression(), typ) p.check_types(p.expression(), typ)
} }

View File

@ -6,27 +6,40 @@ module main
import strings import strings
fn sql_params2params_gen(sql_params []string, qprefix string) string { fn sql_params2params_gen(sql_params []string, sql_types []string, qprefix string) string {
mut params_gen := '' mut params_gen := ''
for i, mparam in sql_params { for i, mparam in sql_params {
param := mparam.trim(` `) param := mparam.trim(` `)
paramtype := sql_types[ i ]
if param[0].is_digit() { if param[0].is_digit() {
params_gen += '${qprefix}params[$i] = int_str($param).str;\n' params_gen += '${qprefix}params[$i] = int_str($param).str;\n'
}else{ }else if param[0] == `\'` {
sparam := param.trim(`\'`) sparam := param.trim(`\'`)
params_gen += '${qprefix}params[$i] = "$sparam";\n' params_gen += '${qprefix}params[$i] = "$sparam";\n'
} else {
// A variable like q.nr_orders
if paramtype == 'int' {
params_gen += '${qprefix}params[$i] = int_str( $param ).str;\n'
}else if paramtype == 'string' {
params_gen += '${qprefix}params[$i] = ${param}.str;\n'
}else{
panic('orm: only int and string variable types are supported in queries')
}
} }
} }
//println('>>>>>>>> params_gen')
//println( params_gen )
return params_gen return params_gen
} }
// `db.select from User where id == 1 && nr_bookings > 0` // `db.select from User where id == 1 && nr_bookings > 0`
fn (p mut Parser) select_query(fn_ph int) string { fn (p mut Parser) select_query(fn_ph int) string {
// NB: qprefix, p.sql_i, p.sql_params SHOULD be reset for each query, // NB: qprefix and { p.sql_i, p.sql_params, p.sql_types } SHOULD be reset for each query,
// because we can have many queries in the _same_ scope. // because we can have many queries in the _same_ scope.
qprefix := p.get_tmp().replace('tmp','sql') + '_' qprefix := p.get_tmp().replace('tmp','sql') + '_'
p.sql_i = 0 p.sql_i = 0
p.sql_params = []string p.sql_params = []string
p.sql_types = []string
mut q := 'select ' mut q := 'select '
p.check(.key_select) p.check(.key_select)
@ -117,7 +130,7 @@ fn (p mut Parser) select_query(fn_ph int) string {
} }
// One object // One object
if query_one { if query_one {
mut params_gen := sql_params2params_gen( p.sql_params, qprefix ) mut params_gen := sql_params2params_gen( p.sql_params, p.sql_types, qprefix )
p.cgen.insert_before(' p.cgen.insert_before('
char* ${qprefix}params[$p.sql_i]; char* ${qprefix}params[$p.sql_i];
@ -142,7 +155,7 @@ ${obj_gen.str()}
// Array // Array
else { else {
q += ' order by id' q += ' order by id'
params_gen := sql_params2params_gen( p.sql_params, qprefix ) params_gen := sql_params2params_gen( p.sql_params, p.sql_types, qprefix )
p.cgen.insert_before('char* ${qprefix}params[$p.sql_i]; p.cgen.insert_before('char* ${qprefix}params[$p.sql_i];
$params_gen $params_gen

View File

@ -38,7 +38,7 @@ fn main() {
println('------------------------------------------------------------------------') println('------------------------------------------------------------------------')
q := Customer{} q := Customer{}
for { for {
anon := db.select from Customer where id = 12345 && nr_orders > q.nr_orders limit 1 or { eprintln('No such customer. Error: $err') break } anon := db.select from Customer where id = 12345 && name = q.name && nr_orders > q.nr_orders limit 1 or { eprintln('No such customer. Error: $err') break }
println('Non existing customer name: $anon.name') println('Non existing customer name: $anon.name')
break break
} }
@ -52,4 +52,5 @@ fn main() {
db.insert(nc) db.insert(nc)
*/ */
} }