From e2d405436754ad070ea4112f79abec87420d5d20 Mon Sep 17 00:00:00 2001 From: wanyaoqi Date: Wed, 29 Aug 2018 17:55:13 +0800 Subject: [PATCH] extend joint filter --- Gopkg.lock | 8 ++--- cmd/climc/shell/shell.go | 2 +- pkg/cloudcommon/db/db_dispatcher.go | 4 +-- .../x/pkg/util/filterclause/filterclause.go | 11 +++--- vendor/yunion.io/x/structarg/structarg.go | 34 ++++++++++++++++--- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index b67bf4ca82..29c5b0c497 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1061,7 +1061,7 @@ [[projects]] branch = "master" - digest = "1:8a2992edca980cb03eb9dc89f62c03c8ab6fe0c5ca4fc1da71eb736aae635f65" + digest = "1:f640bec6e2c558f83117e88f16753d54685c95b8fb83d5660ed6c43e04adde72" name = "yunion.io/x/pkg" packages = [ "gotypes", @@ -1096,7 +1096,7 @@ "utils", ] pruneopts = "UT" - revision = "1e97a2736e5b90c0274b7d391b8d97aa9107725c" + revision = "3bcf68100d212545f2f16b91bb3962bc8b228da7" [[projects]] branch = "master" @@ -1108,11 +1108,11 @@ [[projects]] branch = "master" - digest = "1:71e1b62648868a9083f9e4693145a0154a600591ca548aaf64cae32a10e956e5" + digest = "1:64b263a23f3c35521bb811b2aa9f93f8c7ce1ff06487db12d6aa3fc25705ad2e" name = "yunion.io/x/structarg" packages = ["."] pruneopts = "UT" - revision = "4a5eb8e2cdfbf7f6511561a3c710c116b171f405" + revision = "ec02b19c0bccfc991fc9e850f5a2a543ae43254b" [solve-meta] analyzer-name = "dep" diff --git a/cmd/climc/shell/shell.go b/cmd/climc/shell/shell.go index 03246aa46c..4b0ebbad22 100644 --- a/cmd/climc/shell/shell.go +++ b/cmd/climc/shell/shell.go @@ -28,7 +28,7 @@ type BaseListOptions struct { Search string `help:"Filter results by a simple keyword search"` Meta bool `help:"Piggyback metadata information"` Filter []string `help:"Filters"` - JointFilter []string `help:"Filters with joint table col; joint_tbl(related_key).filter_col.filter_cond(filters)"` + JointFilter []string `help:"Filters with joint table col; joint_tbl.related_key(origin_key).filter_col.filter_cond(filters)"` FilterAny bool `help:"If true, match if any of the filters matches; otherwise, match if all of the filters match"` Admin bool `help:"Is an admin call?"` Tenant string `help:"Tenant ID or Name"` diff --git a/pkg/cloudcommon/db/db_dispatcher.go b/pkg/cloudcommon/db/db_dispatcher.go index 6c8c336a87..5fcbd2dbcd 100644 --- a/pkg/cloudcommon/db/db_dispatcher.go +++ b/pkg/cloudcommon/db/db_dispatcher.go @@ -264,9 +264,9 @@ func applyListItemsGeneralJointFilters(manager IModelManager, q *sqlchemy.SQuery if cond != nil { sq = sq.Filter(cond) if filterAny { - q = q.Filter(sqlchemy.OR(sqlchemy.In(q.Field("id"), sq))) + q = q.Filter(sqlchemy.OR(sqlchemy.In(q.Field(jfc.OriginKey), sq))) } else { - q = q.Filter(sqlchemy.AND(sqlchemy.In(q.Field("id"), sq))) + q = q.Filter(sqlchemy.AND(sqlchemy.In(q.Field(jfc.OriginKey), sq))) } } } diff --git a/vendor/yunion.io/x/pkg/util/filterclause/filterclause.go b/vendor/yunion.io/x/pkg/util/filterclause/filterclause.go index a0928f6527..1bddde5c61 100644 --- a/vendor/yunion.io/x/pkg/util/filterclause/filterclause.go +++ b/vendor/yunion.io/x/pkg/util/filterclause/filterclause.go @@ -16,10 +16,12 @@ type SFilterClause struct { params []string } +// "guestnetworks.guest_id(id).ip_addr.equals(10.168.222.232)" type SJointFilterClause struct { SFilterClause JointModel string RelatedKey string + OriginKey string } func (jfc *SJointFilterClause) GetJointFilter(q *sqlchemy.SQuery) sqlchemy.ICondition { @@ -83,7 +85,7 @@ var ( func init() { filterClausePattern = regexp.MustCompile(`^(\w+)\.(\w+)\((.*)\)`) - jointFilterClausePattern = regexp.MustCompile(`^(\w+)\((\w+)\).(\w+)\.(\w+)\((.*)\)`) + jointFilterClausePattern = regexp.MustCompile(`^(\w+)\.(\w+)\((\w+)\).(\w+)\.(\w+)\((.*)\)`) } func ParseFilterClause(filter string) *SFilterClause { @@ -101,15 +103,16 @@ func ParseJointFilterClause(jointFilter string) *SJointFilterClause { if matches == nil { return nil } - params := utils.FindWords([]byte(matches[5]), 0) + params := utils.FindWords([]byte(matches[6]), 0) jfc := SJointFilterClause{ SFilterClause: SFilterClause{ - field: matches[3], - funcName: matches[4], + field: matches[4], + funcName: matches[5], params: params, }, JointModel: matches[1], RelatedKey: matches[2], + OriginKey: matches[3], } return &jfc } diff --git a/vendor/yunion.io/x/structarg/structarg.go b/vendor/yunion.io/x/structarg/structarg.go index 7f7f6c6414..7eb514b3f0 100644 --- a/vendor/yunion.io/x/structarg/structarg.go +++ b/vendor/yunion.io/x/structarg/structarg.go @@ -423,8 +423,32 @@ func (this *ArgumentParser) Options() interface{} { return this.target } +func (this *SingleArgument) valueIsBool() bool { + rv := this.value + if rv.Kind() == reflect.Bool { + return true + } + + if rv.Kind() == reflect.Ptr && rv.Type().Elem().Kind() == reflect.Bool { + return true + } + return false +} + +func (this *SingleArgument) defaultBoolValue() bool { + rv := this.defValue + if rv.Kind() == reflect.Bool { + return rv.Bool() + } + + if rv.Kind() == reflect.Ptr && rv.Type().Elem().Kind() == reflect.Bool { + return rv.Elem().Bool() + } + panic("expecting bool or *bool type: got " + rv.Type().String()) +} + func (this *SingleArgument) NeedData() bool { - if this.value.Kind() == reflect.Bool { + if this.valueIsBool() { return false } else { return true @@ -539,12 +563,14 @@ func (this *SingleArgument) Reset() { } func (this *SingleArgument) DoAction() error { - if this.value.Type() == gotypes.BoolType { + if this.valueIsBool() { + var v bool if this.useDefault { - this.value.SetBool(!this.defValue.Bool()) + v = !this.defaultBoolValue() } else { - this.value.SetBool(true) + v = true } + gotypes.SetValue(this.value, fmt.Sprintf("%t", v)) this.isSet = true } return nil