orm: allow both integer and string arguments in db.select and db.select limit 1
parent
900df8ecf9
commit
cf06faf09b
|
@ -84,7 +84,7 @@ mut:
|
||||||
is_vweb bool
|
is_vweb bool
|
||||||
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"***)
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -1400,7 +1400,7 @@ 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.sql_params + p.cgen.cut() + ','
|
p.sql_params << p.cgen.cut()
|
||||||
//println('sql params = "$p.sql_params"')
|
//println('sql params = "$p.sql_params"')
|
||||||
} else {
|
} else {
|
||||||
p.check_types(p.expression(), typ)
|
p.check_types(p.expression(), typ)
|
||||||
|
|
|
@ -6,13 +6,27 @@ module main
|
||||||
|
|
||||||
import strings
|
import strings
|
||||||
|
|
||||||
|
fn sql_params2params_gen(sql_params []string, qprefix string) string {
|
||||||
|
mut params_gen := ''
|
||||||
|
for i, mparam in sql_params {
|
||||||
|
param := mparam.trim(` `)
|
||||||
|
if param[0].is_digit() {
|
||||||
|
params_gen += '${qprefix}params[$i] = int_str($param).str;\n'
|
||||||
|
}else{
|
||||||
|
sparam := param.trim(`\'`)
|
||||||
|
params_gen += '${qprefix}params[$i] = "$sparam";\n'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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, p.sql_i, p.sql_params 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 = ''
|
p.sql_params = []string
|
||||||
|
|
||||||
mut q := 'select '
|
mut q := 'select '
|
||||||
p.check(.key_select)
|
p.check(.key_select)
|
||||||
|
@ -103,11 +117,7 @@ fn (p mut Parser) select_query(fn_ph int) string {
|
||||||
}
|
}
|
||||||
// One object
|
// One object
|
||||||
if query_one {
|
if query_one {
|
||||||
mut params_gen := ''
|
mut params_gen := sql_params2params_gen( p.sql_params, qprefix )
|
||||||
params := p.sql_params.split(',')
|
|
||||||
for i, param in params {
|
|
||||||
params_gen += '${qprefix}params[$i] = int_str($param).str;'
|
|
||||||
}
|
|
||||||
p.cgen.insert_before('
|
p.cgen.insert_before('
|
||||||
|
|
||||||
char* ${qprefix}params[$p.sql_i];
|
char* ${qprefix}params[$p.sql_i];
|
||||||
|
@ -131,12 +141,8 @@ ${obj_gen.str()}
|
||||||
}
|
}
|
||||||
// Array
|
// Array
|
||||||
else {
|
else {
|
||||||
q += ' order by id'
|
q += ' order by id'
|
||||||
mut params_gen := ''
|
params_gen := sql_params2params_gen( p.sql_params, qprefix )
|
||||||
params := p.sql_params.split(',')
|
|
||||||
for i, param in params {
|
|
||||||
params_gen += '${qprefix}params[$i] = int_str($param).str;'
|
|
||||||
}
|
|
||||||
p.cgen.insert_before('char* ${qprefix}params[$p.sql_i];
|
p.cgen.insert_before('char* ${qprefix}params[$p.sql_i];
|
||||||
$params_gen
|
$params_gen
|
||||||
|
|
||||||
|
@ -158,8 +164,11 @@ for (int i = 0; i < ${qprefix}rows.len; i++) {
|
||||||
}
|
}
|
||||||
if n == 'count' {
|
if n == 'count' {
|
||||||
return 'int'
|
return 'int'
|
||||||
} else if query_one {
|
} else if query_one {
|
||||||
return 'Option_$table_name'
|
opt_type := 'Option_$table_name'
|
||||||
|
p.cgen.typedefs << 'typedef Option $opt_type;'
|
||||||
|
p.table.register_type( opt_type )
|
||||||
|
return opt_type
|
||||||
} else {
|
} else {
|
||||||
p.register_array('array_$table_name')
|
p.register_array('array_$table_name')
|
||||||
return 'array_$table_name'
|
return 'array_$table_name'
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
module main
|
||||||
|
|
||||||
|
import pg
|
||||||
|
|
||||||
|
struct Customer {
|
||||||
|
id int
|
||||||
|
name string
|
||||||
|
nr_orders int
|
||||||
|
country string
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
db := pg.connect(pg.Config{host: '127.0.0.1' user: 'myuser' dbname: 'mydb'})
|
||||||
|
|
||||||
|
nr_customers := db.select count from Customer
|
||||||
|
println('Total customers: $nr_customers')
|
||||||
|
|
||||||
|
// V syntax can be used to build queries
|
||||||
|
println('------------------------------------------------------------------------')
|
||||||
|
bg_customers := db.select from Customer where country = 'Bulgaria' && id != 2
|
||||||
|
for customer in bg_customers {
|
||||||
|
println('$customer.country | $customer.id - $customer.name')
|
||||||
|
}
|
||||||
|
|
||||||
|
println('------------------------------------------------------------------------')
|
||||||
|
ru_customers := db.select from Customer where country = 'Russia'
|
||||||
|
for customer in ru_customers {
|
||||||
|
println('$customer.country | $customer.id - $customer.name')
|
||||||
|
}
|
||||||
|
|
||||||
|
// by adding `limit 1` we tell V that there will be only one object
|
||||||
|
println('------------------------------------------------------------------------')
|
||||||
|
existing := db.select from Customer where id = 1 limit 1 or { panic(err) }
|
||||||
|
println('Existing customer name: $existing.name')
|
||||||
|
println('Existing customer full information:')
|
||||||
|
println(existing)
|
||||||
|
|
||||||
|
println('------------------------------------------------------------------------')
|
||||||
|
q := Customer{}
|
||||||
|
for {
|
||||||
|
anon := db.select from Customer where id = 12345 && nr_orders > q.nr_orders limit 1 or { eprintln('No such customer. Error: $err') break }
|
||||||
|
println('Non existing customer name: $anon.name')
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: insert a new customer
|
||||||
|
/*
|
||||||
|
nc := Customer{
|
||||||
|
name: 'John Doe'
|
||||||
|
nr_orders: 10
|
||||||
|
}
|
||||||
|
db.insert(nc)
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
--
|
||||||
|
-- PostgreSQL database dump
|
||||||
|
--
|
||||||
|
|
||||||
|
-- Dumped from database version 9.5.19
|
||||||
|
-- Dumped by pg_dump version 9.5.19
|
||||||
|
|
||||||
|
SET statement_timeout = 0;
|
||||||
|
SET lock_timeout = 0;
|
||||||
|
SET client_encoding = 'UTF8';
|
||||||
|
SET standard_conforming_strings = on;
|
||||||
|
SELECT pg_catalog.set_config('search_path', '', false);
|
||||||
|
SET check_function_bodies = false;
|
||||||
|
SET xmloption = content;
|
||||||
|
SET client_min_messages = warning;
|
||||||
|
SET row_security = off;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner:
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner:
|
||||||
|
--
|
||||||
|
|
||||||
|
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
|
||||||
|
|
||||||
|
|
||||||
|
SET default_tablespace = '';
|
||||||
|
|
||||||
|
SET default_with_oids = false;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: customer; Type: TABLE; Schema: public; Owner: myuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE public.customer (
|
||||||
|
id integer NOT NULL,
|
||||||
|
name text DEFAULT ''::text,
|
||||||
|
nr_orders integer DEFAULT 0,
|
||||||
|
country text DEFAULT 'England'::text,
|
||||||
|
created_at timestamp without time zone DEFAULT now()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE public.customer OWNER TO myuser;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: customer_id_seq; Type: SEQUENCE; Schema: public; Owner: myuser
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SEQUENCE public.customer_id_seq
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE public.customer_id_seq OWNER TO myuser;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: customer_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: myuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER SEQUENCE public.customer_id_seq OWNED BY public.customer.id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: id; Type: DEFAULT; Schema: public; Owner: myuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.customer ALTER COLUMN id SET DEFAULT nextval('public.customer_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Data for Name: customer; Type: TABLE DATA; Schema: public; Owner: myuser
|
||||||
|
--
|
||||||
|
|
||||||
|
COPY public.customer (id, name, nr_orders, country, created_at) FROM stdin;
|
||||||
|
2 Pippi Långstrump 3 Bulgaria 2019-08-19 09:41:30.78888
|
||||||
|
1 Bilbo Begins 11 Bulgaria 2019-08-19 09:40:31.396807
|
||||||
|
3 Viktualia Rullgardina 0 Bulgaria 2019-08-19 09:42:52.723223
|
||||||
|
4 Krusmynta Efraimsdotter 5 Bulgaria 2019-08-19 09:43:04.083209
|
||||||
|
5 Ana Karenina 0 Russia 2019-08-20 15:41:50.244971
|
||||||
|
7 Jiji Lolobridgida 0 Italy 2019-08-20 15:42:26.020113
|
||||||
|
6 Viktor Savashkin 8 Russia 2019-08-20 15:42:07.213557
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: customer_id_seq; Type: SEQUENCE SET; Schema: public; Owner: myuser
|
||||||
|
--
|
||||||
|
|
||||||
|
SELECT pg_catalog.setval('public.customer_id_seq', 1, true);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: customer_pkey; Type: CONSTRAINT; Schema: public; Owner: myuser
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.customer
|
||||||
|
ADD CONSTRAINT customer_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: SCHEMA public; Type: ACL; Schema: -; Owner: postgres
|
||||||
|
--
|
||||||
|
|
||||||
|
REVOKE ALL ON SCHEMA public FROM PUBLIC;
|
||||||
|
REVOKE ALL ON SCHEMA public FROM postgres;
|
||||||
|
GRANT ALL ON SCHEMA public TO postgres;
|
||||||
|
GRANT ALL ON SCHEMA public TO PUBLIC;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- PostgreSQL database dump complete
|
||||||
|
--
|
||||||
|
|
Loading…
Reference in New Issue