diff --git a/vlib/orm/orm_func.v b/vlib/orm/orm_func.v index 825ee7abe5..32d6d36036 100644 --- a/vlib/orm/orm_func.v +++ b/vlib/orm/orm_func.v @@ -43,12 +43,28 @@ pub fn (qb_ &QueryBuilder[T]) reset() &QueryBuilder[T] { return qb } -// where create a `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 `operator` incldue: `=`, `!=`, `<>`, `>=`, `<=`, `>`, `<`, `LIKE`, `ILIKE`, `IS NULL`, `IS NOT NULL` // 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] { mut qb := unsafe { qb_ } + if qb.where.fields.len > 0 { + // skip first field + qb.where.is_and << true // and + } + qb.parse_conditions(condition, params)! + qb.config.has_where = true + return qb +} + +// or_where create a `where` clause, it will `OR` with previous `where` clause. +pub fn (qb_ &QueryBuilder[T]) or_where(condition string, params ...Primitive) !&QueryBuilder[T] { + mut qb := unsafe { qb_ } + if qb.where.fields.len > 0 { + // skip first field + qb.where.is_and << false // or + } qb.parse_conditions(condition, params)! qb.config.has_where = true return qb diff --git a/vlib/orm/orm_func_test.v b/vlib/orm/orm_func_test.v index abfb4d8113..a39aae5b5e 100644 --- a/vlib/orm/orm_func_test.v +++ b/vlib/orm/orm_func_test.v @@ -496,6 +496,12 @@ fn test_orm_func_stmts() { assert selected_users[0].name == 'Silly' assert selected_users.len == 1 + // chain where + and_where := qb.where('salary > ?', 2000)!.where('age > ?', 40)!.query()! + assert and_where.len == 1 + or_where := qb.where('salary > ?', 2000)!.or_where('age > ? OR score > ?', 40, 85)!.query()! + assert or_where.len == 9 + // chain calls final_users := qb .drop()!