diff --git a/CHANGES.md b/CHANGES.md index 429c27814..7d88f2643 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,12 @@ Release Notes. +## 0.5.0 + +### Features + +- List all properties in a group. + ## 0.4.0 ### Features diff --git a/api/proto/banyandb/common/v1/common.proto b/api/proto/banyandb/common/v1/common.proto index fb8572f38..16fe8e678 100644 --- a/api/proto/banyandb/common/v1/common.proto +++ b/api/proto/banyandb/common/v1/common.proto @@ -36,7 +36,7 @@ message Metadata { // group contains a set of options, like retention policy, max string group = 1; // name of the entity - string name = 2 [(validate.rules).string.min_len = 1]; + string name = 2; uint32 id = 3; // readonly. create_revision is the revision of last creation on this key. int64 create_revision = 4; diff --git a/api/proto/banyandb/property/v1/rpc.proto b/api/proto/banyandb/property/v1/rpc.proto index 10a09c78f..8151c8bc0 100644 --- a/api/proto/banyandb/property/v1/rpc.proto +++ b/api/proto/banyandb/property/v1/rpc.proto @@ -102,6 +102,9 @@ service PropertyService { rpc List(ListRequest) returns (ListResponse) { option (google.api.http) = { get: "/v1/property/lists/{container.group}/{container.name}/{ids}/{tags}" + additional_bindings { + get: "/v1/property/lists/{container.group}" + } }; } } diff --git a/bydbctl/internal/cmd/property.go b/bydbctl/internal/cmd/property.go index 47fa68fd6..27c8420d5 100644 --- a/bydbctl/internal/cmd/property.go +++ b/bydbctl/internal/cmd/property.go @@ -35,6 +35,7 @@ var ( propertySchemaPathWithoutTagParams = propertySchemaPath + "/{group}/{name}/{id}" propertySchemaPathWithTagParams = propertySchemaPath + "/{group}/{name}/{id}/{tag}" propertyListSchemaPathWithTagParams = propertySchemaPath + "/lists/{group}/{name}/{ids}/{tags}" + propertyListSchemaPath = propertySchemaPath + "/lists/{group}" ) func newPropertyCmd() *cobra.Command { @@ -103,12 +104,15 @@ func newPropertyCmd() *cobra.Command { Short: "List properties", RunE: func(_ *cobra.Command, _ []string) (err error) { return rest(parseFromFlags, func(request request) (*resty.Response, error) { + if len(request.name) == 0 { + return request.req.SetPathParam("group", request.group).Get(getPath(propertyListSchemaPath)) + } return request.req.SetPathParam("name", request.name).SetPathParam("group", request.group). SetPathParam("ids", request.ids()).SetPathParam("tags", request.tags()).Get(getPath(propertyListSchemaPathWithTagParams)) }, yamlPrinter) }, } - bindNameFlag(listCmd) + listCmd.Flags().StringVarP(&name, "name", "n", "", "the name of the resource") listCmd.Flags().StringArrayVarP(&ids, "ids", "", nil, "id selector") listCmd.Flags().StringArrayVarP(&tags, "tags", "t", nil, "tag selector") diff --git a/bydbctl/internal/cmd/property_test.go b/bydbctl/internal/cmd/property_test.go index 614375d1c..191591c62 100644 --- a/bydbctl/internal/cmd/property_test.go +++ b/bydbctl/internal/cmd/property_test.go @@ -201,7 +201,44 @@ tags: Expect(err).To(MatchError("rpc error: code = NotFound desc = banyandb: resource not found")) }) - It("list property", func() { + It("list all properties", func() { + // create another property for list operation + rootCmd.SetArgs([]string{"property", "apply", "-f", "-"}) + rootCmd.SetIn(strings.NewReader(` +metadata: + container: + group: ui-template + name: service + id: spring +tags: + - key: content + value: + str: + value: bar + - key: state + value: + int: + value: 1 +`)) + out := capturer.CaptureStdout(func() { + err := rootCmd.Execute() + Expect(err).NotTo(HaveOccurred()) + }) + Expect(out).To(ContainSubstring("created: true")) + Expect(out).To(ContainSubstring("tagsNum: 2")) + // list + rootCmd.SetArgs([]string{"property", "list", "-g", "ui-template"}) + out = capturer.CaptureStdout(func() { + cmd.ResetFlags() + err := rootCmd.Execute() + Expect(err).NotTo(HaveOccurred()) + }) + resp := new(propertyv1.ListResponse) + helpers.UnmarshalYAML([]byte(out), resp) + Expect(resp.Property).To(HaveLen(2)) + }) + + It("list properties in a container", func() { // create another property for list operation rootCmd.SetArgs([]string{"property", "apply", "-f", "-"}) rootCmd.SetIn(strings.NewReader(` @@ -229,6 +266,7 @@ tags: // list rootCmd.SetArgs([]string{"property", "list", "-g", "ui-template", "-n", "service"}) out = capturer.CaptureStdout(func() { + cmd.ResetFlags() err := rootCmd.Execute() Expect(err).NotTo(HaveOccurred()) }) diff --git a/bydbctl/internal/cmd/root.go b/bydbctl/internal/cmd/root.go index 7c7a16e21..c7956d8c2 100644 --- a/bydbctl/internal/cmd/root.go +++ b/bydbctl/internal/cmd/root.go @@ -42,6 +42,14 @@ var ( } ) +// ResetFlags resets the flags. +func ResetFlags() { + filePath = "" + name = "" + start = "" + end = "" +} + // Execute executes the root command. func Execute() error { return rootCmd.Execute() diff --git a/docs/crud/property.md b/docs/crud/property.md index 05378438c..7f28d856f 100644 --- a/docs/crud/property.md +++ b/docs/crud/property.md @@ -95,9 +95,17 @@ $ bydbctl property delete -g sw -n ui_template --id General-Service --tags state ## List operation -List operation lists all properties. +List operation lists all properties in a group. -### Examples of listing +### Examples of listing in a group + +```shell +$ bydbctl property list -g sw +``` + +List operation lists all properties in a group with a name. + +### Examples of listing in a group with a name ```shell $ bydbctl property list -g sw -n ui_template diff --git a/test/integration/other/property_test.go b/test/integration/other/property_test.go index d7ec7c661..79f8f38b0 100644 --- a/test/integration/other/property_test.go +++ b/test/integration/other/property_test.go @@ -140,7 +140,14 @@ var _ = Describe("Property application", func() { Expect(conn.Close()).To(Succeed()) deferFn() }) - It("lists properties", func() { + It("lists properties in a group", func() { + got, err := client.List(context.Background(), &propertyv1.ListRequest{Container: &commonv1.Metadata{ + Group: "g", + }}) + Expect(err).NotTo(HaveOccurred()) + Expect(len(got.Property)).To(Equal(1)) + }) + It("lists properties in a container", func() { got, err := client.List(context.Background(), &propertyv1.ListRequest{Container: md.Container}) Expect(err).NotTo(HaveOccurred()) Expect(len(got.Property)).To(Equal(1))