mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: check db
type implements orm.Connection
and isn't an Option
. (#18078)
This commit is contained in:
parent
9eee131423
commit
e8df5a7861
@ -7,8 +7,9 @@ import v.token
|
|||||||
import v.util
|
import v.util
|
||||||
|
|
||||||
const (
|
const (
|
||||||
fkey_attr_name = 'fkey'
|
fkey_attr_name = 'fkey'
|
||||||
v_orm_prefix = 'V ORM'
|
v_orm_prefix = 'V ORM'
|
||||||
|
connection_interface_name = 'orm.Connection'
|
||||||
)
|
)
|
||||||
|
|
||||||
type ORMExpr = ast.SqlExpr | ast.SqlStmt
|
type ORMExpr = ast.SqlExpr | ast.SqlStmt
|
||||||
@ -18,8 +19,13 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type {
|
|||||||
defer {
|
defer {
|
||||||
c.inside_sql = false
|
c.inside_sql = false
|
||||||
}
|
}
|
||||||
sym := c.table.sym(node.table_expr.typ)
|
|
||||||
|
if !c.check_db_expr(node.db_expr) {
|
||||||
|
return ast.void_type
|
||||||
|
}
|
||||||
c.ensure_type_exists(node.table_expr.typ, node.pos) or { return ast.void_type }
|
c.ensure_type_exists(node.table_expr.typ, node.pos) or { return ast.void_type }
|
||||||
|
sym := c.table.sym(node.table_expr.typ)
|
||||||
|
|
||||||
old_ts := c.cur_orm_ts
|
old_ts := c.cur_orm_ts
|
||||||
c.cur_orm_ts = *sym
|
c.cur_orm_ts = *sym
|
||||||
defer {
|
defer {
|
||||||
@ -150,6 +156,9 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Checker) sql_stmt(mut node ast.SqlStmt) ast.Type {
|
fn (mut c Checker) sql_stmt(mut node ast.SqlStmt) ast.Type {
|
||||||
|
if !c.check_db_expr(node.db_expr) {
|
||||||
|
return ast.void_type
|
||||||
|
}
|
||||||
node.db_expr_type = c.table.unaliased_type(c.expr(node.db_expr))
|
node.db_expr_type = c.table.unaliased_type(c.expr(node.db_expr))
|
||||||
|
|
||||||
for mut line in node.lines {
|
for mut line in node.lines {
|
||||||
@ -496,3 +505,27 @@ fn (mut c Checker) check_orm_or_expr(expr ORMExpr) {
|
|||||||
c.expected_or_type = ast.void_type
|
c.expected_or_type = ast.void_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut c Checker) check_db_expr(db_expr &ast.Expr) bool {
|
||||||
|
connection_type_index := c.table.find_type_idx(checker.connection_interface_name)
|
||||||
|
connection_typ := ast.Type(connection_type_index)
|
||||||
|
db_expr_type := c.expr(db_expr)
|
||||||
|
|
||||||
|
// If we didn't find `orm.Connection`, we don't have any imported modules
|
||||||
|
// that depend on `orm` and implement the `orm.Connection` interface.
|
||||||
|
if connection_type_index == 0 {
|
||||||
|
c.error('expected a type that implements the `${checker.connection_interface_name}` interface',
|
||||||
|
db_expr.pos())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
is_implemented := c.type_implements(db_expr_type, connection_typ, db_expr.pos())
|
||||||
|
is_option := db_expr_type.has_flag(.option)
|
||||||
|
|
||||||
|
if is_implemented && is_option {
|
||||||
|
c.error(c.expected_msg(db_expr_type, db_expr_type.clear_flag(.option)), db_expr.pos())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
vlib/v/checker/tests/like_operator_with_non_string_type_error.vv:10:36: error: the right operand of the `like` operator must be a string type
|
vlib/v/checker/tests/like_operator_with_non_string_type_error.vv:12:36: error: the right operand of the `like` operator must be a string type
|
||||||
8 |
|
10 |
|
||||||
9 | println(sql db {
|
11 | println(sql db {
|
||||||
10 | select from User where name like 10
|
12 | select from User where name like 10
|
||||||
| ~~
|
| ~~
|
||||||
11 | }!)
|
13 | }!)
|
||||||
12 |
|
14 |
|
||||||
vlib/v/checker/tests/like_operator_with_non_string_type_error.vv:14:26: error: the left operand of the `like` operator must be an identifier with a string type
|
vlib/v/checker/tests/like_operator_with_non_string_type_error.vv:16:26: error: the left operand of the `like` operator must be an identifier with a string type
|
||||||
12 |
|
14 |
|
||||||
13 | println(sql db {
|
15 | println(sql db {
|
||||||
14 | select from User where 10 like true
|
16 | select from User where 10 like true
|
||||||
| ~~
|
| ~~
|
||||||
15 | }!)
|
17 | }!)
|
||||||
16 | }
|
18 | }
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
|
import db.sqlite
|
||||||
|
|
||||||
struct User {
|
struct User {
|
||||||
id int [primary]
|
id int [primary]
|
||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
db := ''
|
db := sqlite.connect(':memory:')!
|
||||||
|
|
||||||
println(sql db {
|
println(sql db {
|
||||||
select from User where name like 10
|
select from User where name like 10
|
||||||
|
28
vlib/v/checker/tests/orm_db_expr_option_error.out
Normal file
28
vlib/v/checker/tests/orm_db_expr_option_error.out
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
vlib/v/checker/tests/orm_db_expr_option_error.vv:16:11: error: expected `sqlite.DB`, not `?sqlite.DB`
|
||||||
|
14 | db_option := connect_option()
|
||||||
|
15 |
|
||||||
|
16 | _ := sql db_option {
|
||||||
|
| ~~~~~~~~~
|
||||||
|
17 | select from Account
|
||||||
|
18 | }!
|
||||||
|
vlib/v/checker/tests/orm_db_expr_option_error.vv:22:11: error: `Account` doesn't implement method `select` of interface `orm.Connection`
|
||||||
|
20 | account := Account{}
|
||||||
|
21 |
|
||||||
|
22 | _ := sql account {
|
||||||
|
| ~~~~~~~
|
||||||
|
23 | select from Account
|
||||||
|
24 | }!
|
||||||
|
vlib/v/checker/tests/orm_db_expr_option_error.vv:26:6: error: `Account` doesn't implement method `select` of interface `orm.Connection`
|
||||||
|
24 | }!
|
||||||
|
25 |
|
||||||
|
26 | sql account {
|
||||||
|
| ~~~~~~~
|
||||||
|
27 | insert account into Account
|
||||||
|
28 | }!
|
||||||
|
vlib/v/checker/tests/orm_db_expr_option_error.vv:30:6: error: expected `sqlite.DB`, not `?sqlite.DB`
|
||||||
|
28 | }!
|
||||||
|
29 |
|
||||||
|
30 | sql db_option {
|
||||||
|
| ~~~~~~~~~
|
||||||
|
31 | insert account into Account
|
||||||
|
32 | }!
|
33
vlib/v/checker/tests/orm_db_expr_option_error.vv
Normal file
33
vlib/v/checker/tests/orm_db_expr_option_error.vv
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
module main
|
||||||
|
|
||||||
|
import db.sqlite
|
||||||
|
|
||||||
|
struct Account {
|
||||||
|
id int [primary]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn connect_option() ?sqlite.DB {
|
||||||
|
return sqlite.connect(':memory:') or { return none }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
db_option := connect_option()
|
||||||
|
|
||||||
|
_ := sql db_option {
|
||||||
|
select from Account
|
||||||
|
}!
|
||||||
|
|
||||||
|
account := Account{}
|
||||||
|
|
||||||
|
_ := sql account {
|
||||||
|
select from Account
|
||||||
|
}!
|
||||||
|
|
||||||
|
sql account {
|
||||||
|
insert account into Account
|
||||||
|
}!
|
||||||
|
|
||||||
|
sql db_option {
|
||||||
|
insert account into Account
|
||||||
|
}!
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
vlib/v/parser/tests/orm_no_error_handler.vv:8:7: error: V ORM returns a result, so it should have either an `or {}` block, or `!` at the end
|
vlib/v/parser/tests/orm_no_error_handler.vv:10:7: error: V ORM returns a result, so it should have either an `or {}` block, or `!` at the end
|
||||||
6 | db := true
|
8 | db := sqlite.connect(':memory:')!
|
||||||
7 |
|
9 |
|
||||||
8 | _ := sql db {
|
10 | _ := sql db {
|
||||||
| ~~~~~~~~
|
| ~~~~~~~~
|
||||||
9 | select from User
|
11 | select from User
|
||||||
10 | }
|
12 | }
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import db.sqlite
|
||||||
|
|
||||||
struct User {
|
struct User {
|
||||||
id int
|
id int
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
db := true
|
db := sqlite.connect(':memory:')!
|
||||||
|
|
||||||
_ := sql db {
|
_ := sql db {
|
||||||
select from User
|
select from User
|
||||||
|
Loading…
x
Reference in New Issue
Block a user