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
|
||||
|
||||
const (
|
||||
fkey_attr_name = 'fkey'
|
||||
v_orm_prefix = 'V ORM'
|
||||
fkey_attr_name = 'fkey'
|
||||
v_orm_prefix = 'V ORM'
|
||||
connection_interface_name = 'orm.Connection'
|
||||
)
|
||||
|
||||
type ORMExpr = ast.SqlExpr | ast.SqlStmt
|
||||
@ -18,8 +19,13 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type {
|
||||
defer {
|
||||
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 }
|
||||
sym := c.table.sym(node.table_expr.typ)
|
||||
|
||||
old_ts := c.cur_orm_ts
|
||||
c.cur_orm_ts = *sym
|
||||
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 {
|
||||
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))
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
8 |
|
||||
9 | println(sql db {
|
||||
10 | select from User where name like 10
|
||||
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
|
||||
10 |
|
||||
11 | println(sql db {
|
||||
12 | select from User where name like 10
|
||||
| ~~
|
||||
11 | }!)
|
||||
12 |
|
||||
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
|
||||
12 |
|
||||
13 | println(sql db {
|
||||
14 | select from User where 10 like true
|
||||
13 | }!)
|
||||
14 |
|
||||
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
|
||||
14 |
|
||||
15 | println(sql db {
|
||||
16 | select from User where 10 like true
|
||||
| ~~
|
||||
15 | }!)
|
||||
16 | }
|
||||
17 | }!)
|
||||
18 | }
|
||||
|
@ -1,10 +1,12 @@
|
||||
import db.sqlite
|
||||
|
||||
struct User {
|
||||
id int [primary]
|
||||
name string
|
||||
}
|
||||
|
||||
fn main() {
|
||||
db := ''
|
||||
db := sqlite.connect(':memory:')!
|
||||
|
||||
println(sql db {
|
||||
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
|
||||
6 | db := true
|
||||
7 |
|
||||
8 | _ := sql db {
|
||||
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
|
||||
8 | db := sqlite.connect(':memory:')!
|
||||
9 |
|
||||
10 | _ := sql db {
|
||||
| ~~~~~~~~
|
||||
9 | select from User
|
||||
10 | }
|
||||
11 | select from User
|
||||
12 | }
|
||||
|
@ -1,9 +1,11 @@
|
||||
import db.sqlite
|
||||
|
||||
struct User {
|
||||
id int
|
||||
}
|
||||
|
||||
fn main() {
|
||||
db := true
|
||||
db := sqlite.connect(':memory:')!
|
||||
|
||||
_ := sql db {
|
||||
select from User
|
||||
|
Loading…
x
Reference in New Issue
Block a user