mirror of
https://github.com/astaxie/beego.git
synced 2024-11-25 20:51:29 +00:00
all panic use Error
This commit is contained in:
parent
aaf1490ff5
commit
658a671b79
32
orm/db.go
32
orm/db.go
@ -58,7 +58,7 @@ func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, cols []string,
|
|||||||
if fi, _ = mi.fields.GetByAny(column); fi != nil {
|
if fi, _ = mi.fields.GetByAny(column); fi != nil {
|
||||||
column = fi.column
|
column = fi.column
|
||||||
} else {
|
} else {
|
||||||
panic(fmt.Sprintf("wrong db field/column name `%s` for model `%s`", column, mi.fullName))
|
panic(fmt.Errorf("wrong db field/column name `%s` for model `%s`", column, mi.fullName))
|
||||||
}
|
}
|
||||||
if fi.dbcol == false || fi.auto && skipAuto {
|
if fi.dbcol == false || fi.auto && skipAuto {
|
||||||
continue
|
continue
|
||||||
@ -360,7 +360,7 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
|
|||||||
values := make([]interface{}, 0, len(params))
|
values := make([]interface{}, 0, len(params))
|
||||||
for col, val := range params {
|
for col, val := range params {
|
||||||
if fi, ok := mi.fields.GetByAny(col); ok == false || fi.dbcol == false {
|
if fi, ok := mi.fields.GetByAny(col); ok == false || fi.dbcol == false {
|
||||||
panic(fmt.Sprintf("wrong field/column name `%s`", col))
|
panic(fmt.Errorf("wrong field/column name `%s`", col))
|
||||||
} else {
|
} else {
|
||||||
columns = append(columns, fi.column)
|
columns = append(columns, fi.column)
|
||||||
values = append(values, val)
|
values = append(values, val)
|
||||||
@ -368,7 +368,7 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(columns) == 0 {
|
if len(columns) == 0 {
|
||||||
panic("update params cannot empty")
|
panic(fmt.Errorf("update params cannot empty"))
|
||||||
}
|
}
|
||||||
|
|
||||||
tables := newDbTables(mi, d.ins)
|
tables := newDbTables(mi, d.ins)
|
||||||
@ -438,7 +438,7 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cond == nil || cond.IsEmpty() {
|
if cond == nil || cond.IsEmpty() {
|
||||||
panic("delete operation cannot execute without condition")
|
panic(fmt.Errorf("delete operation cannot execute without condition"))
|
||||||
}
|
}
|
||||||
|
|
||||||
Q := d.ins.TableQuote()
|
Q := d.ins.TableQuote()
|
||||||
@ -533,9 +533,9 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
|
|||||||
|
|
||||||
if errTyp {
|
if errTyp {
|
||||||
if one {
|
if one {
|
||||||
panic(fmt.Sprintf("wrong object type `%s` for rows scan, need *%s", val.Type(), mi.fullName))
|
panic(fmt.Errorf("wrong object type `%s` for rows scan, need *%s", val.Type(), mi.fullName))
|
||||||
} else {
|
} else {
|
||||||
panic(fmt.Sprintf("wrong object type `%s` for rows scan, need *[]*%s or *[]%s", val.Type(), mi.fullName, mi.fullName))
|
panic(fmt.Errorf("wrong object type `%s` for rows scan, need *[]*%s or *[]%s", val.Type(), mi.fullName, mi.fullName))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -559,7 +559,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
|
|||||||
maps[fi.column] = true
|
maps[fi.column] = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic(fmt.Sprintf("wrong field/column name `%s`", col))
|
panic(fmt.Errorf("wrong field/column name `%s`", col))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if hasRel {
|
if hasRel {
|
||||||
@ -717,7 +717,7 @@ func (d *dbBase) GenerateOperatorSql(mi *modelInfo, fi *fieldInfo, operator stri
|
|||||||
params := getFlatParams(fi, args, tz)
|
params := getFlatParams(fi, args, tz)
|
||||||
|
|
||||||
if len(params) == 0 {
|
if len(params) == 0 {
|
||||||
panic(fmt.Sprintf("operator `%s` need at least one args", operator))
|
panic(fmt.Errorf("operator `%s` need at least one args", operator))
|
||||||
}
|
}
|
||||||
arg := params[0]
|
arg := params[0]
|
||||||
|
|
||||||
@ -729,7 +729,7 @@ func (d *dbBase) GenerateOperatorSql(mi *modelInfo, fi *fieldInfo, operator stri
|
|||||||
sql = fmt.Sprintf("IN (%s)", strings.Join(marks, ", "))
|
sql = fmt.Sprintf("IN (%s)", strings.Join(marks, ", "))
|
||||||
} else {
|
} else {
|
||||||
if len(params) > 1 {
|
if len(params) > 1 {
|
||||||
panic(fmt.Sprintf("operator `%s` need 1 args not %d", operator, len(params)))
|
panic(fmt.Errorf("operator `%s` need 1 args not %d", operator, len(params)))
|
||||||
}
|
}
|
||||||
sql = d.ins.OperatorSql(operator)
|
sql = d.ins.OperatorSql(operator)
|
||||||
switch operator {
|
switch operator {
|
||||||
@ -758,7 +758,7 @@ func (d *dbBase) GenerateOperatorSql(mi *modelInfo, fi *fieldInfo, operator stri
|
|||||||
}
|
}
|
||||||
params = nil
|
params = nil
|
||||||
} else {
|
} else {
|
||||||
panic(fmt.Sprintf("operator `%s` need a bool value not `%T`", operator, arg))
|
panic(fmt.Errorf("operator `%s` need a bool value not `%T`", operator, arg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -779,13 +779,13 @@ func (d *dbBase) setColsValues(mi *modelInfo, ind *reflect.Value, cols []string,
|
|||||||
|
|
||||||
value, err := d.convertValueFromDB(fi, val, tz)
|
value, err := d.convertValueFromDB(fi, val, tz)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("Raw value: `%v` %s", val, err.Error()))
|
panic(fmt.Errorf("Raw value: `%v` %s", val, err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = d.setFieldValue(fi, value, field)
|
_, err = d.setFieldValue(fi, value, field)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("Raw value: `%v` %s", val, err.Error()))
|
panic(fmt.Errorf("Raw value: `%v` %s", val, err.Error()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1034,7 +1034,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
|
|||||||
case *ParamsList:
|
case *ParamsList:
|
||||||
typ = 3
|
typ = 3
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unsupport read values type `%T`", container))
|
panic(fmt.Errorf("unsupport read values type `%T`", container))
|
||||||
}
|
}
|
||||||
|
|
||||||
tables := newDbTables(mi, d.ins)
|
tables := newDbTables(mi, d.ins)
|
||||||
@ -1117,7 +1117,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
|
|||||||
|
|
||||||
value, err := d.convertValueFromDB(fi, val, tz)
|
value, err := d.convertValueFromDB(fi, val, tz)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("db value convert failed `%v` %s", val, err.Error()))
|
panic(fmt.Errorf("db value convert failed `%v` %s", val, err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
params[columns[i]] = value
|
params[columns[i]] = value
|
||||||
@ -1132,7 +1132,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
|
|||||||
|
|
||||||
value, err := d.convertValueFromDB(fi, val, tz)
|
value, err := d.convertValueFromDB(fi, val, tz)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("db value convert failed `%v` %s", val, err.Error()))
|
panic(fmt.Errorf("db value convert failed `%v` %s", val, err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
params = append(params, value)
|
params = append(params, value)
|
||||||
@ -1146,7 +1146,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
|
|||||||
|
|
||||||
value, err := d.convertValueFromDB(fi, val, tz)
|
value, err := d.convertValueFromDB(fi, val, tz)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("db value convert failed `%v` %s", val, err.Error()))
|
panic(fmt.Errorf("db value convert failed `%v` %s", val, err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
list = append(list, value)
|
list = append(list, value)
|
||||||
|
@ -126,7 +126,7 @@ func (t *dbTables) parseRelated(rels []string, depth int) {
|
|||||||
jtl = jt
|
jtl = jt
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
panic(fmt.Sprintf("unknown model/table name `%s`", ex))
|
panic(fmt.Errorf("unknown model/table name `%s`", ex))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ func registerModel(model interface{}, prefix string) {
|
|||||||
typ := ind.Type()
|
typ := ind.Type()
|
||||||
|
|
||||||
if val.Kind() != reflect.Ptr {
|
if val.Kind() != reflect.Ptr {
|
||||||
panic(fmt.Sprintf("<orm.RegisterModel> cannot use non-ptr model struct `%s`", getFullName(typ)))
|
panic(fmt.Errorf("<orm.RegisterModel> cannot use non-ptr model struct `%s`", getFullName(typ)))
|
||||||
}
|
}
|
||||||
|
|
||||||
table := getTableName(val)
|
table := getTableName(val)
|
||||||
@ -177,7 +177,7 @@ func bootStrap() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if added == false {
|
if added == false {
|
||||||
panic(fmt.Sprintf("cannot generate auto reverse field info `%s` to `%s`", fi.fullName, ffi.fullName))
|
panic(fmt.Errorf("cannot generate auto reverse field info `%s` to `%s`", fi.fullName, ffi.fullName))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
orm/orm.go
10
orm/orm.go
@ -44,13 +44,13 @@ func (o *orm) getMiInd(md interface{}) (mi *modelInfo, ind reflect.Value) {
|
|||||||
ind = reflect.Indirect(val)
|
ind = reflect.Indirect(val)
|
||||||
typ := ind.Type()
|
typ := ind.Type()
|
||||||
if val.Kind() != reflect.Ptr {
|
if val.Kind() != reflect.Ptr {
|
||||||
panic(fmt.Sprintf("<Ormer> cannot use non-ptr model struct `%s`", getFullName(typ)))
|
panic(fmt.Errorf("<Ormer> cannot use non-ptr model struct `%s`", getFullName(typ)))
|
||||||
}
|
}
|
||||||
name := getFullName(typ)
|
name := getFullName(typ)
|
||||||
if mi, ok := modelCache.getByFN(name); ok {
|
if mi, ok := modelCache.getByFN(name); ok {
|
||||||
return mi, ind
|
return mi, ind
|
||||||
}
|
}
|
||||||
panic(fmt.Sprintf("<Ormer> table: `%s` not found, maybe not RegisterModel", name))
|
panic(fmt.Errorf("<Ormer> table: `%s` not found, maybe not RegisterModel", name))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *orm) Read(md interface{}, cols ...string) error {
|
func (o *orm) Read(md interface{}, cols ...string) error {
|
||||||
@ -141,14 +141,14 @@ func (o *orm) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if qs == nil {
|
if qs == nil {
|
||||||
panic(fmt.Sprintf("<Ormer.QueryTable> table name: `%s` not exists", name))
|
panic(fmt.Errorf("<Ormer.QueryTable> table name: `%s` not exists", name))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *orm) Using(name string) error {
|
func (o *orm) Using(name string) error {
|
||||||
if o.isTx {
|
if o.isTx {
|
||||||
panic("<Ormer.Using> transaction has been start, cannot change db")
|
panic(fmt.Errorf("<Ormer.Using> transaction has been start, cannot change db"))
|
||||||
}
|
}
|
||||||
if al, ok := dataBaseCache.get(name); ok {
|
if al, ok := dataBaseCache.get(name); ok {
|
||||||
o.alias = al
|
o.alias = al
|
||||||
@ -158,7 +158,7 @@ func (o *orm) Using(name string) error {
|
|||||||
o.db = al.DB
|
o.db = al.DB
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return errors.New(fmt.Sprintf("<Ormer.Using> unknown db alias name `%s`", name))
|
return fmt.Errorf("<Ormer.Using> unknown db alias name `%s`", name)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package orm
|
package orm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ func NewCondition() *Condition {
|
|||||||
|
|
||||||
func (c Condition) And(expr string, args ...interface{}) *Condition {
|
func (c Condition) And(expr string, args ...interface{}) *Condition {
|
||||||
if expr == "" || len(args) == 0 {
|
if expr == "" || len(args) == 0 {
|
||||||
panic("<Condition.And> args cannot empty")
|
panic(fmt.Errorf("<Condition.And> args cannot empty"))
|
||||||
}
|
}
|
||||||
c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args})
|
c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args})
|
||||||
return &c
|
return &c
|
||||||
@ -36,7 +37,7 @@ func (c Condition) And(expr string, args ...interface{}) *Condition {
|
|||||||
|
|
||||||
func (c Condition) AndNot(expr string, args ...interface{}) *Condition {
|
func (c Condition) AndNot(expr string, args ...interface{}) *Condition {
|
||||||
if expr == "" || len(args) == 0 {
|
if expr == "" || len(args) == 0 {
|
||||||
panic("<Condition.AndNot> args cannot empty")
|
panic(fmt.Errorf("<Condition.AndNot> args cannot empty"))
|
||||||
}
|
}
|
||||||
c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args, isNot: true})
|
c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args, isNot: true})
|
||||||
return &c
|
return &c
|
||||||
@ -45,7 +46,7 @@ func (c Condition) AndNot(expr string, args ...interface{}) *Condition {
|
|||||||
func (c *Condition) AndCond(cond *Condition) *Condition {
|
func (c *Condition) AndCond(cond *Condition) *Condition {
|
||||||
c = c.clone()
|
c = c.clone()
|
||||||
if c == cond {
|
if c == cond {
|
||||||
panic("cannot use self as sub cond")
|
panic(fmt.Errorf("<Condition.AndCond> cannot use self as sub cond"))
|
||||||
}
|
}
|
||||||
if cond != nil {
|
if cond != nil {
|
||||||
c.params = append(c.params, condValue{cond: cond, isCond: true})
|
c.params = append(c.params, condValue{cond: cond, isCond: true})
|
||||||
@ -55,7 +56,7 @@ func (c *Condition) AndCond(cond *Condition) *Condition {
|
|||||||
|
|
||||||
func (c Condition) Or(expr string, args ...interface{}) *Condition {
|
func (c Condition) Or(expr string, args ...interface{}) *Condition {
|
||||||
if expr == "" || len(args) == 0 {
|
if expr == "" || len(args) == 0 {
|
||||||
panic("<Condition.Or> args cannot empty")
|
panic(fmt.Errorf("<Condition.Or> args cannot empty"))
|
||||||
}
|
}
|
||||||
c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args, isOr: true})
|
c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args, isOr: true})
|
||||||
return &c
|
return &c
|
||||||
@ -63,7 +64,7 @@ func (c Condition) Or(expr string, args ...interface{}) *Condition {
|
|||||||
|
|
||||||
func (c Condition) OrNot(expr string, args ...interface{}) *Condition {
|
func (c Condition) OrNot(expr string, args ...interface{}) *Condition {
|
||||||
if expr == "" || len(args) == 0 {
|
if expr == "" || len(args) == 0 {
|
||||||
panic("<Condition.OrNot> args cannot empty")
|
panic(fmt.Errorf("<Condition.OrNot> args cannot empty"))
|
||||||
}
|
}
|
||||||
c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args, isNot: true, isOr: true})
|
c.params = append(c.params, condValue{exprs: strings.Split(expr, ExprSep), args: args, isNot: true, isOr: true})
|
||||||
return &c
|
return &c
|
||||||
@ -72,7 +73,7 @@ func (c Condition) OrNot(expr string, args ...interface{}) *Condition {
|
|||||||
func (c *Condition) OrCond(cond *Condition) *Condition {
|
func (c *Condition) OrCond(cond *Condition) *Condition {
|
||||||
c = c.clone()
|
c = c.clone()
|
||||||
if c == cond {
|
if c == cond {
|
||||||
panic("cannot use self as sub cond")
|
panic(fmt.Errorf("<Condition.OrCond> cannot use self as sub cond"))
|
||||||
}
|
}
|
||||||
if cond != nil {
|
if cond != nil {
|
||||||
c.params = append(c.params, condValue{cond: cond, isCond: true, isOr: true})
|
c.params = append(c.params, condValue{cond: cond, isCond: true, isOr: true})
|
||||||
|
@ -23,10 +23,10 @@ func (o *insertSet) Insert(md interface{}) (int64, error) {
|
|||||||
typ := ind.Type()
|
typ := ind.Type()
|
||||||
name := getFullName(typ)
|
name := getFullName(typ)
|
||||||
if val.Kind() != reflect.Ptr {
|
if val.Kind() != reflect.Ptr {
|
||||||
panic(fmt.Sprintf("<Inserter.Insert> cannot use non-ptr model struct `%s`", name))
|
panic(fmt.Errorf("<Inserter.Insert> cannot use non-ptr model struct `%s`", name))
|
||||||
}
|
}
|
||||||
if name != o.mi.fullName {
|
if name != o.mi.fullName {
|
||||||
panic(fmt.Sprintf("<Inserter.Insert> need model `%s` but found `%s`", o.mi.fullName, name))
|
panic(fmt.Errorf("<Inserter.Insert> need model `%s` but found `%s`", o.mi.fullName, name))
|
||||||
}
|
}
|
||||||
id, err := o.orm.alias.DbBaser.InsertStmt(o.stmt, o.mi, ind, o.orm.alias.TZ)
|
id, err := o.orm.alias.DbBaser.InsertStmt(o.stmt, o.mi, ind, o.orm.alias.TZ)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -67,7 +67,7 @@ func (o querySet) RelatedSel(params ...interface{}) QuerySeter {
|
|||||||
case int:
|
case int:
|
||||||
o.relDepth = val
|
o.relDepth = val
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("<QuerySeter.RelatedSel> wrong param kind: %v", val))
|
panic(fmt.Errorf("<QuerySeter.RelatedSel> wrong param kind: %v", val))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,7 +314,7 @@ func (o *rawSet) loopSetRefs(refs []interface{}, sIdxes [][]int, sInds []reflect
|
|||||||
|
|
||||||
func (o *rawSet) QueryRow(containers ...interface{}) error {
|
func (o *rawSet) QueryRow(containers ...interface{}) error {
|
||||||
if len(containers) == 0 {
|
if len(containers) == 0 {
|
||||||
panic("<RawSeter.QueryRow> need at least one arg")
|
panic(fmt.Errorf("<RawSeter.QueryRow> need at least one arg"))
|
||||||
}
|
}
|
||||||
|
|
||||||
refs := make([]interface{}, 0, len(containers))
|
refs := make([]interface{}, 0, len(containers))
|
||||||
@ -327,7 +327,7 @@ func (o *rawSet) QueryRow(containers ...interface{}) error {
|
|||||||
ind := reflect.Indirect(val)
|
ind := reflect.Indirect(val)
|
||||||
|
|
||||||
if val.Kind() != reflect.Ptr {
|
if val.Kind() != reflect.Ptr {
|
||||||
panic("<RawSeter.QueryRow> all args must be use ptr")
|
panic(fmt.Errorf("<RawSeter.QueryRow> all args must be use ptr"))
|
||||||
}
|
}
|
||||||
|
|
||||||
etyp := ind.Type()
|
etyp := ind.Type()
|
||||||
@ -377,7 +377,7 @@ func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) {
|
|||||||
val := reflect.ValueOf(container)
|
val := reflect.ValueOf(container)
|
||||||
sInd := reflect.Indirect(val)
|
sInd := reflect.Indirect(val)
|
||||||
if val.Kind() != reflect.Ptr || sInd.Kind() != reflect.Slice {
|
if val.Kind() != reflect.Ptr || sInd.Kind() != reflect.Slice {
|
||||||
panic("<RawSeter.QueryRows> all args must be use ptr slice")
|
panic(fmt.Errorf("<RawSeter.QueryRows> all args must be use ptr slice"))
|
||||||
}
|
}
|
||||||
|
|
||||||
etyp := sInd.Type().Elem()
|
etyp := sInd.Type().Elem()
|
||||||
@ -440,7 +440,7 @@ func (o *rawSet) readValues(container interface{}) (int64, error) {
|
|||||||
case *ParamsList:
|
case *ParamsList:
|
||||||
typ = 3
|
typ = 3
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("<RawSeter> unsupport read values type `%T`", container))
|
panic(fmt.Errorf("<RawSeter> unsupport read values type `%T`", container))
|
||||||
}
|
}
|
||||||
|
|
||||||
query := o.query
|
query := o.query
|
||||||
|
Loading…
Reference in New Issue
Block a user