mirror of
https://github.com/vlang/v.git
synced 2025-09-14 15:02:33 +03:00
parent
8320da22e7
commit
2944710abd
2 changed files with 20 additions and 3 deletions
|
@ -3,7 +3,8 @@ module orm
|
||||||
import time
|
import time
|
||||||
import strings.textscanner
|
import strings.textscanner
|
||||||
|
|
||||||
const operators = ['=', '!=', '<>', '>=', '<=', '>', '<', 'LIKE', 'ILIKE', 'IS NULL', 'IS NOT NULL']!
|
const operators = ['=', '!=', '<>', '>=', '<=', '>', '<', 'LIKE', 'ILIKE', 'IS NULL', 'IS NOT NULL',
|
||||||
|
'IN', 'NOT IN']!
|
||||||
|
|
||||||
@[heap]
|
@[heap]
|
||||||
pub struct QueryBuilder[T] {
|
pub struct QueryBuilder[T] {
|
||||||
|
@ -45,7 +46,7 @@ pub fn (qb_ &QueryBuilder[T]) reset() &QueryBuilder[T] {
|
||||||
|
|
||||||
// where create a `where` clause, it will `AND` with previous `where` clause.
|
// where create a `where` clause, it will `AND` with previous `where` clause.
|
||||||
// valid token in the `condition` include: `field's names`, `operator`, `(`, `)`, `?`, `AND`, `OR`, `||`, `&&`,
|
// valid token in the `condition` include: `field's names`, `operator`, `(`, `)`, `?`, `AND`, `OR`, `||`, `&&`,
|
||||||
// valid `operator` incldue: `=`, `!=`, `<>`, `>=`, `<=`, `>`, `<`, `LIKE`, `ILIKE`, `IS NULL`, `IS NOT NULL`
|
// valid `operator` incldue: `=`, `!=`, `<>`, `>=`, `<=`, `>`, `<`, `LIKE`, `ILIKE`, `IS NULL`, `IS NOT NULL`, `IN`, `NOT IN`
|
||||||
// example: `where('(a > ? AND b <= ?) OR (c <> ? AND (x = ? OR y = ?))', a, b, c, x, y)`
|
// example: `where('(a > ? AND b <= ?) OR (c <> ? AND (x = ? OR y = ?))', a, b, c, x, y)`
|
||||||
pub fn (qb_ &QueryBuilder[T]) where(condition string, params ...Primitive) !&QueryBuilder[T] {
|
pub fn (qb_ &QueryBuilder[T]) where(condition string, params ...Primitive) !&QueryBuilder[T] {
|
||||||
mut qb := unsafe { qb_ }
|
mut qb := unsafe { qb_ }
|
||||||
|
@ -102,9 +103,13 @@ fn (mut ss MyTextScanner) next_tok() string {
|
||||||
ss.pos += 7
|
ss.pos += 7
|
||||||
return 'IS NULL'
|
return 'IS NULL'
|
||||||
}
|
}
|
||||||
|
if ss.input[ss.pos..].starts_with('NOT IN') {
|
||||||
|
ss.pos += 6
|
||||||
|
return 'NOT IN'
|
||||||
|
}
|
||||||
if ss.remaining() >= 2 {
|
if ss.remaining() >= 2 {
|
||||||
two_chars := ss.input[ss.pos..ss.pos + 2]
|
two_chars := ss.input[ss.pos..ss.pos + 2]
|
||||||
if two_chars in ['>=', '<=', '<>', '!=', '||', '&&'] {
|
if two_chars in ['>=', '<=', '<>', '!=', '||', '&&', 'IN'] {
|
||||||
ss.pos += 2
|
ss.pos += 2
|
||||||
return two_chars
|
return two_chars
|
||||||
}
|
}
|
||||||
|
@ -215,6 +220,12 @@ fn (qb_ &QueryBuilder[T]) parse_conditions(conds string, params []Primitive) ! {
|
||||||
'IS NOT NULL' {
|
'IS NOT NULL' {
|
||||||
OperationKind.is_not_null
|
OperationKind.is_not_null
|
||||||
}
|
}
|
||||||
|
'IN' {
|
||||||
|
OperationKind.in
|
||||||
|
}
|
||||||
|
'NOT IN' {
|
||||||
|
OperationKind.not_in
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
parse_error('${@FN}(): unsupported operator: `${tok}`', s.last_tok_start,
|
parse_error('${@FN}(): unsupported operator: `${tok}`', s.last_tok_start,
|
||||||
conds)!
|
conds)!
|
||||||
|
|
|
@ -90,6 +90,12 @@ fn test_orm_func_where() {
|
||||||
qb.reset()
|
qb.reset()
|
||||||
qb.where('((age = ? OR (salary > ? AND id < ?)) AND (name LIKE ?))', 1, 2, 3, '%test%')!
|
qb.where('((age = ? OR (salary > ? AND id < ?)) AND (name LIKE ?))', 1, 2, 3, '%test%')!
|
||||||
assert qb.where.parentheses == [[1, 2], [0, 2], [3, 3], [0, 3]]
|
assert qb.where.parentheses == [[1, 2], [0, 2], [3, 3], [0, 3]]
|
||||||
|
|
||||||
|
// in and not in
|
||||||
|
qb.reset()
|
||||||
|
qb.where('name IN ? AND age NOT IN ?', ['Tom'], [2])!
|
||||||
|
assert qb.where.fields == ['name', 'age']
|
||||||
|
assert qb.where.kinds == [.in, .not_in]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_orm_func_stmts() {
|
fn test_orm_func_stmts() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue