feat: Add bucket schema management commands (#52)

* feat: update generated client to include schema-management APIs
* feat: implement interfaces to decode flags and CSV
* feat: implement decoders for different measurement schema column formats
* feat: extend bucket CLI commands to support schema type property
* feat: add CLI commands to manage measurement schema
* test: add unit tests for bucket schema create, update and list commands
This commit is contained in:
Stuart Carnie 2021-05-06 00:12:11 +10:00 committed by GitHub
parent 4a1e6223f0
commit 7eca7c0bb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 4014 additions and 11 deletions

View File

@ -2,6 +2,7 @@ package main
import (
"github.com/influxdata/influx-cli/v2/internal"
"github.com/influxdata/influx-cli/v2/internal/api"
"github.com/influxdata/influx-cli/v2/pkg/cli/middleware"
"github.com/urfave/cli/v2"
)
@ -44,7 +45,9 @@ func newBucketCmd() *cli.Command {
}
func newBucketCreateCmd() *cli.Command {
var params internal.BucketsCreateParams
params := internal.BucketsCreateParams{
SchemaType: api.SCHEMATYPE_IMPLICIT,
}
return &cli.Command{
Name: "create",
Usage: "Create bucket",
@ -91,6 +94,12 @@ func newBucketCreateCmd() *cli.Command {
EnvVars: []string{"INFLUX_ORG"},
Destination: &params.OrgName,
},
&cli.GenericFlag{
Name: "schema-type",
Usage: "The schema type (implicit, explicit)",
DefaultText: "implicit",
Value: &params.SchemaType,
},
),
Action: func(ctx *cli.Context) error {
clients := getBucketsClient(ctx)

189
cmd/influx/bucket_schema.go Normal file
View File

@ -0,0 +1,189 @@
package main
import (
"github.com/influxdata/influx-cli/v2/internal"
"github.com/influxdata/influx-cli/v2/internal/cmd/bucket_schema"
"github.com/influxdata/influx-cli/v2/pkg/cli/middleware"
"github.com/influxdata/influx-cli/v2/pkg/influxid"
"github.com/urfave/cli/v2"
)
func withBucketSchemaClient() cli.BeforeFunc {
return middleware.WithBeforeFns(
withCli(),
withApi(true),
func(ctx *cli.Context) error {
c := getCLI(ctx)
client := getAPI(ctx)
ctx.App.Metadata["measurement_schema"] = bucket_schema.Client{
BucketApi: client.BucketsApi,
BucketSchemasApi: client.BucketSchemasApi,
CLI: c,
}
return nil
})
}
func getBucketSchemaClient(ctx *cli.Context) bucket_schema.Client {
i, ok := ctx.App.Metadata["measurement_schema"].(bucket_schema.Client)
if !ok {
panic("missing measurement schema client")
}
return i
}
func newBucketSchemaCmd() *cli.Command {
return &cli.Command{
Name: "bucket-schema",
Usage: "Bucket schema management commands",
Subcommands: []*cli.Command{
newBucketSchemaCreateCmd(),
newBucketSchemaUpdateCmd(),
newBucketSchemaListCmd(),
},
}
}
func newBucketSchemaCreateCmd() *cli.Command {
var params struct {
internal.OrgBucketParams
Name string
ColumnsFile string
ColumnsFormat bucket_schema.ColumnsFormat
ExtendedOutput bool
}
return &cli.Command{
Name: "create",
Usage: "Create a measurement schema for a bucket",
Before: withBucketSchemaClient(),
Flags: append(
commonFlags,
append(
getOrgBucketFlags(&params.OrgBucketParams),
&cli.StringFlag{
Name: "name",
Usage: "Name of the measurement",
Destination: &params.Name,
},
&cli.StringFlag{
Name: "columns-file",
Usage: "A path referring to list of column definitions",
Destination: &params.ColumnsFile,
},
&cli.GenericFlag{
Name: "columns-format",
Usage: "The format of the columns file. \"auto\" will attempt to guess the format.",
DefaultText: "auto",
Value: &params.ColumnsFormat,
},
&cli.BoolFlag{
Name: "extended-output",
Usage: "Print column information for each measurement",
Aliases: []string{"x"},
Destination: &params.ExtendedOutput,
},
)...,
),
Action: func(ctx *cli.Context) error {
return getBucketSchemaClient(ctx).
Create(ctx.Context, bucket_schema.CreateParams{
OrgBucketParams: params.OrgBucketParams,
Name: params.Name,
Stdin: ctx.App.Reader,
ColumnsFile: params.ColumnsFile,
ColumnsFormat: params.ColumnsFormat,
ExtendedOutput: params.ExtendedOutput,
})
},
}
}
func newBucketSchemaUpdateCmd() *cli.Command {
var params struct {
internal.OrgBucketParams
ID influxid.ID
Name string
ColumnsFile string
ColumnsFormat bucket_schema.ColumnsFormat
ExtendedOutput bool
}
return &cli.Command{
Name: "update",
Usage: "Update a measurement schema for a bucket",
Before: withBucketSchemaClient(),
Flags: append(
commonFlags,
append(
getOrgBucketFlags(&params.OrgBucketParams),
&cli.GenericFlag{
Name: "id",
Usage: "ID of the measurement",
Value: &params.ID,
},
&cli.StringFlag{
Name: "name",
Usage: "Name of the measurement",
Destination: &params.Name,
},
&cli.StringFlag{
Name: "columns-file",
Usage: "A path referring to list of column definitions",
Destination: &params.ColumnsFile,
},
&cli.GenericFlag{
Name: "columns-format",
Usage: "The format of the columns file. \"auto\" will attempt to guess the format.",
DefaultText: "auto",
Value: &params.ColumnsFormat,
},
&cli.BoolFlag{
Name: "extended-output",
Usage: "Print column information for each measurement",
Aliases: []string{"x"},
Destination: &params.ExtendedOutput,
},
)...,
),
Action: func(ctx *cli.Context) error {
return getBucketSchemaClient(ctx).
Update(ctx.Context, bucket_schema.UpdateParams{
OrgBucketParams: params.OrgBucketParams,
ID: params.ID.String(),
Name: params.Name,
Stdin: ctx.App.Reader,
ColumnsFile: params.ColumnsFile,
ColumnsFormat: params.ColumnsFormat,
ExtendedOutput: params.ExtendedOutput,
})
},
}
}
func newBucketSchemaListCmd() *cli.Command {
var params bucket_schema.ListParams
return &cli.Command{
Name: "list",
Usage: "List schemas for a bucket",
Before: withBucketSchemaClient(),
Flags: append(
commonFlags,
append(
getOrgBucketFlags(&params.OrgBucketParams),
&cli.StringFlag{
Name: "name",
Usage: "Name of single measurement to find",
Destination: &params.Name,
},
&cli.BoolFlag{
Name: "extended-output",
Usage: "Print column information for each measurement",
Aliases: []string{"x"},
Destination: &params.ExtendedOutput,
},
)...,
),
Action: func(ctx *cli.Context) error {
return getBucketSchemaClient(ctx).List(ctx.Context, params)
},
}
}

View File

@ -198,6 +198,7 @@ var app = cli.App{
newWriteCmd(),
newBucketCmd(),
newCompletionCmd(),
newBucketSchemaCmd(),
},
}

36
cmd/influx/params.go Normal file
View File

@ -0,0 +1,36 @@
package main
import (
"github.com/influxdata/influx-cli/v2/internal"
"github.com/urfave/cli/v2"
)
func getOrgBucketFlags(c *internal.OrgBucketParams) []cli.Flag {
return []cli.Flag{
&cli.GenericFlag{
Name: "bucket-id",
Usage: "The bucket ID, required if name isn't provided",
Aliases: []string{"i"},
Value: &c.BucketID,
},
&cli.StringFlag{
Name: "bucket",
Usage: "The bucket name, org or org-id will be required by choosing this",
Aliases: []string{"n"},
Destination: &c.BucketName,
},
&cli.GenericFlag{
Name: "org-id",
Usage: "The ID of the organization",
EnvVars: []string{"INFLUX_ORG_ID"},
Value: &c.OrgID,
},
&cli.StringFlag{
Name: "org",
Usage: "The name of the organization",
Aliases: []string{"o"},
EnvVars: []string{"INFLUX_ORG"},
Destination: &c.OrgName,
},
}
}

View File

@ -6,7 +6,7 @@ declare -r API_DIR="${ROOT_DIR}/internal/api"
declare -r GENERATED_PATTERN='^// Code generated .* DO NOT EDIT\.$'
declare -r GENERATOR_DOCKER_IMG=openapitools/openapi-generator-cli:v5.1.0
declare -r OPENAPI_COMMIT=e41d5e327a67e472a46cd6edfe673496e1b066dd
declare -r OPENAPI_COMMIT=af4e3efa496c8adcd2838145652fdd8d63a90702
# Clean up all the generated files in the target directory.
rm $(grep -Elr "${GENERATED_PATTERN}" "${API_DIR}")

4
go.mod
View File

@ -5,8 +5,12 @@ go 1.16
require (
github.com/AlecAivazis/survey/v2 v2.2.9
github.com/BurntSushi/toml v0.3.1
github.com/MakeNowJust/heredoc/v2 v2.0.1
github.com/daixiang0/gci v0.2.8
github.com/fujiwara/shapeio v1.0.0
github.com/gocarina/gocsv v0.0.0-20210408192840-02d7211d929d
github.com/golang/mock v1.5.0
github.com/google/go-cmp v0.5.5
github.com/kr/pretty v0.1.0 // indirect
github.com/stretchr/testify v1.7.0
github.com/urfave/cli/v2 v2.3.0

10
go.sum
View File

@ -2,6 +2,8 @@ github.com/AlecAivazis/survey/v2 v2.2.9 h1:LWvJtUswz/W9/zVVXELrmlvdwWcKE60ZAw0FW
github.com/AlecAivazis/survey/v2 v2.2.9/go.mod h1:9DYvHgXtiXm6nCn+jXnOXLKbH+Yo9u8fAS/SduGdoPk=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/MakeNowJust/heredoc/v2 v2.0.1 h1:rlCHh70XXXv7toz95ajQWOWQnN4WNLt0TdpZYIR/J6A=
github.com/MakeNowJust/heredoc/v2 v2.0.1/go.mod h1:6/2Abh5s+hc3g9nbWLe9ObDIOhaRrqsyY9MWy+4JdRM=
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
@ -15,6 +17,12 @@ github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/fujiwara/shapeio v1.0.0 h1:xG5D9oNqCSUUbryZ/jQV3cqe1v2suEjwPIcEg1gKM8M=
github.com/fujiwara/shapeio v1.0.0/go.mod h1:LmEmu6L/8jetyj1oewewFb7bZCNRwE7wLCUNzDLaLVA=
github.com/gocarina/gocsv v0.0.0-20210408192840-02d7211d929d h1:r3mStZSyjKhEcgbJ5xtv7kT5PZw/tDiFBTMgQx2qsXE=
github.com/gocarina/gocsv v0.0.0-20210408192840-02d7211d929d/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI=
github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
@ -39,6 +47,7 @@ github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
@ -77,6 +86,7 @@ golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@ -0,0 +1,718 @@
/*
* Subset of Influx API covered by Influx CLI
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 2.0.0
*/
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
package api
import (
"bytes"
_context "context"
_ioutil "io/ioutil"
_nethttp "net/http"
_neturl "net/url"
"strings"
)
// Linger please
var (
_ _context.Context
)
type BucketSchemasApi interface {
/*
* CreateMeasurementSchema Create a new measurement schema for this bucket
* @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
* @param bucketID The ID of the bucket
* @return ApiCreateMeasurementSchemaRequest
*/
CreateMeasurementSchema(ctx _context.Context, bucketID string) ApiCreateMeasurementSchemaRequest
/*
* CreateMeasurementSchemaExecute executes the request
* @return MeasurementSchema
*/
CreateMeasurementSchemaExecute(r ApiCreateMeasurementSchemaRequest) (MeasurementSchema, *_nethttp.Response, error)
/*
* GetMeasurementSchema Fetch schema information for a measurement
* @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
* @param bucketID The ID of the bucket
* @param measurementID The ID of the measurement
* @return ApiGetMeasurementSchemaRequest
*/
GetMeasurementSchema(ctx _context.Context, bucketID string, measurementID string) ApiGetMeasurementSchemaRequest
/*
* GetMeasurementSchemaExecute executes the request
* @return MeasurementSchema
*/
GetMeasurementSchemaExecute(r ApiGetMeasurementSchemaRequest) (MeasurementSchema, *_nethttp.Response, error)
/*
* GetMeasurementSchemas Retrieve a list of measurement schemas defined for this bucket
* @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
* @param bucketID The ID of the bucket
* @return ApiGetMeasurementSchemasRequest
*/
GetMeasurementSchemas(ctx _context.Context, bucketID string) ApiGetMeasurementSchemasRequest
/*
* GetMeasurementSchemasExecute executes the request
* @return MeasurementSchemaList
*/
GetMeasurementSchemasExecute(r ApiGetMeasurementSchemasRequest) (MeasurementSchemaList, *_nethttp.Response, error)
/*
* UpdateMeasurementSchema Update existing measurement schema
* @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
* @param bucketID The ID of the bucket
* @param measurementID The ID of the measurement
* @return ApiUpdateMeasurementSchemaRequest
*/
UpdateMeasurementSchema(ctx _context.Context, bucketID string, measurementID string) ApiUpdateMeasurementSchemaRequest
/*
* UpdateMeasurementSchemaExecute executes the request
* @return MeasurementSchema
*/
UpdateMeasurementSchemaExecute(r ApiUpdateMeasurementSchemaRequest) (MeasurementSchema, *_nethttp.Response, error)
}
// BucketSchemasApiService BucketSchemasApi service
type BucketSchemasApiService service
type ApiCreateMeasurementSchemaRequest struct {
ctx _context.Context
ApiService BucketSchemasApi
bucketID string
org *string
orgID *string
measurementSchemaCreateRequest *MeasurementSchemaCreateRequest
}
func (r ApiCreateMeasurementSchemaRequest) BucketID(bucketID string) ApiCreateMeasurementSchemaRequest {
r.bucketID = bucketID
return r
}
func (r ApiCreateMeasurementSchemaRequest) GetBucketID() string {
return r.bucketID
}
func (r ApiCreateMeasurementSchemaRequest) Org(org string) ApiCreateMeasurementSchemaRequest {
r.org = &org
return r
}
func (r ApiCreateMeasurementSchemaRequest) GetOrg() *string {
return r.org
}
func (r ApiCreateMeasurementSchemaRequest) OrgID(orgID string) ApiCreateMeasurementSchemaRequest {
r.orgID = &orgID
return r
}
func (r ApiCreateMeasurementSchemaRequest) GetOrgID() *string {
return r.orgID
}
func (r ApiCreateMeasurementSchemaRequest) MeasurementSchemaCreateRequest(measurementSchemaCreateRequest MeasurementSchemaCreateRequest) ApiCreateMeasurementSchemaRequest {
r.measurementSchemaCreateRequest = &measurementSchemaCreateRequest
return r
}
func (r ApiCreateMeasurementSchemaRequest) GetMeasurementSchemaCreateRequest() *MeasurementSchemaCreateRequest {
return r.measurementSchemaCreateRequest
}
func (r ApiCreateMeasurementSchemaRequest) Execute() (MeasurementSchema, *_nethttp.Response, error) {
return r.ApiService.CreateMeasurementSchemaExecute(r)
}
/*
* CreateMeasurementSchema Create a new measurement schema for this bucket
* @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
* @param bucketID The ID of the bucket
* @return ApiCreateMeasurementSchemaRequest
*/
func (a *BucketSchemasApiService) CreateMeasurementSchema(ctx _context.Context, bucketID string) ApiCreateMeasurementSchemaRequest {
return ApiCreateMeasurementSchemaRequest{
ApiService: a,
ctx: ctx,
bucketID: bucketID,
}
}
/*
* Execute executes the request
* @return MeasurementSchema
*/
func (a *BucketSchemasApiService) CreateMeasurementSchemaExecute(r ApiCreateMeasurementSchemaRequest) (MeasurementSchema, *_nethttp.Response, error) {
var (
localVarHTTPMethod = _nethttp.MethodPost
localVarPostBody interface{}
localVarFormFileName string
localVarFileName string
localVarFileBytes []byte
localVarReturnValue MeasurementSchema
)
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BucketSchemasApiService.CreateMeasurementSchema")
if err != nil {
return localVarReturnValue, nil, GenericOpenAPIError{error: err.Error()}
}
localVarPath := localBasePath + "/buckets/{bucketID}/schema/measurements"
localVarPath = strings.Replace(localVarPath, "{"+"bucketID"+"}", _neturl.PathEscape(parameterToString(r.bucketID, "")), -1)
localVarHeaderParams := make(map[string]string)
localVarQueryParams := _neturl.Values{}
localVarFormParams := _neturl.Values{}
if r.org != nil {
localVarQueryParams.Add("org", parameterToString(*r.org, ""))
}
if r.orgID != nil {
localVarQueryParams.Add("orgID", parameterToString(*r.orgID, ""))
}
// to determine the Content-Type header
localVarHTTPContentTypes := []string{"application/json"}
// set Content-Type header
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
if localVarHTTPContentType != "" {
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
}
// to determine the Accept header
localVarHTTPHeaderAccepts := []string{"application/json"}
// set Accept header
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
if localVarHTTPHeaderAccept != "" {
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
}
// body params
localVarPostBody = r.measurementSchemaCreateRequest
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
if err != nil {
return localVarReturnValue, nil, err
}
localVarHTTPResponse, err := a.client.callAPI(req)
if err != nil || localVarHTTPResponse == nil {
return localVarReturnValue, localVarHTTPResponse, err
}
localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
localVarHTTPResponse.Body.Close()
localVarHTTPResponse.Body = _ioutil.NopCloser(bytes.NewBuffer(localVarBody))
if err != nil {
return localVarReturnValue, localVarHTTPResponse, err
}
if localVarHTTPResponse.StatusCode >= 300 {
newErr := GenericOpenAPIError{
body: localVarBody,
error: localVarHTTPResponse.Status,
}
if localVarHTTPResponse.StatusCode == 400 {
var v Error
err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
if err != nil {
newErr.error = err.Error()
return localVarReturnValue, localVarHTTPResponse, newErr
}
newErr.model = &v
}
return localVarReturnValue, localVarHTTPResponse, newErr
}
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
if err != nil {
newErr := GenericOpenAPIError{
body: localVarBody,
error: err.Error(),
}
return localVarReturnValue, localVarHTTPResponse, newErr
}
return localVarReturnValue, localVarHTTPResponse, nil
}
type ApiGetMeasurementSchemaRequest struct {
ctx _context.Context
ApiService BucketSchemasApi
bucketID string
measurementID string
org *string
orgID *string
}
func (r ApiGetMeasurementSchemaRequest) BucketID(bucketID string) ApiGetMeasurementSchemaRequest {
r.bucketID = bucketID
return r
}
func (r ApiGetMeasurementSchemaRequest) GetBucketID() string {
return r.bucketID
}
func (r ApiGetMeasurementSchemaRequest) MeasurementID(measurementID string) ApiGetMeasurementSchemaRequest {
r.measurementID = measurementID
return r
}
func (r ApiGetMeasurementSchemaRequest) GetMeasurementID() string {
return r.measurementID
}
func (r ApiGetMeasurementSchemaRequest) Org(org string) ApiGetMeasurementSchemaRequest {
r.org = &org
return r
}
func (r ApiGetMeasurementSchemaRequest) GetOrg() *string {
return r.org
}
func (r ApiGetMeasurementSchemaRequest) OrgID(orgID string) ApiGetMeasurementSchemaRequest {
r.orgID = &orgID
return r
}
func (r ApiGetMeasurementSchemaRequest) GetOrgID() *string {
return r.orgID
}
func (r ApiGetMeasurementSchemaRequest) Execute() (MeasurementSchema, *_nethttp.Response, error) {
return r.ApiService.GetMeasurementSchemaExecute(r)
}
/*
* GetMeasurementSchema Fetch schema information for a measurement
* @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
* @param bucketID The ID of the bucket
* @param measurementID The ID of the measurement
* @return ApiGetMeasurementSchemaRequest
*/
func (a *BucketSchemasApiService) GetMeasurementSchema(ctx _context.Context, bucketID string, measurementID string) ApiGetMeasurementSchemaRequest {
return ApiGetMeasurementSchemaRequest{
ApiService: a,
ctx: ctx,
bucketID: bucketID,
measurementID: measurementID,
}
}
/*
* Execute executes the request
* @return MeasurementSchema
*/
func (a *BucketSchemasApiService) GetMeasurementSchemaExecute(r ApiGetMeasurementSchemaRequest) (MeasurementSchema, *_nethttp.Response, error) {
var (
localVarHTTPMethod = _nethttp.MethodGet
localVarPostBody interface{}
localVarFormFileName string
localVarFileName string
localVarFileBytes []byte
localVarReturnValue MeasurementSchema
)
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BucketSchemasApiService.GetMeasurementSchema")
if err != nil {
return localVarReturnValue, nil, GenericOpenAPIError{error: err.Error()}
}
localVarPath := localBasePath + "/buckets/{bucketID}/schema/measurements/{measurementID}"
localVarPath = strings.Replace(localVarPath, "{"+"bucketID"+"}", _neturl.PathEscape(parameterToString(r.bucketID, "")), -1)
localVarPath = strings.Replace(localVarPath, "{"+"measurementID"+"}", _neturl.PathEscape(parameterToString(r.measurementID, "")), -1)
localVarHeaderParams := make(map[string]string)
localVarQueryParams := _neturl.Values{}
localVarFormParams := _neturl.Values{}
if r.org != nil {
localVarQueryParams.Add("org", parameterToString(*r.org, ""))
}
if r.orgID != nil {
localVarQueryParams.Add("orgID", parameterToString(*r.orgID, ""))
}
// to determine the Content-Type header
localVarHTTPContentTypes := []string{}
// set Content-Type header
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
if localVarHTTPContentType != "" {
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
}
// to determine the Accept header
localVarHTTPHeaderAccepts := []string{"application/json"}
// set Accept header
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
if localVarHTTPHeaderAccept != "" {
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
}
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
if err != nil {
return localVarReturnValue, nil, err
}
localVarHTTPResponse, err := a.client.callAPI(req)
if err != nil || localVarHTTPResponse == nil {
return localVarReturnValue, localVarHTTPResponse, err
}
localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
localVarHTTPResponse.Body.Close()
localVarHTTPResponse.Body = _ioutil.NopCloser(bytes.NewBuffer(localVarBody))
if err != nil {
return localVarReturnValue, localVarHTTPResponse, err
}
if localVarHTTPResponse.StatusCode >= 300 {
newErr := GenericOpenAPIError{
body: localVarBody,
error: localVarHTTPResponse.Status,
}
return localVarReturnValue, localVarHTTPResponse, newErr
}
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
if err != nil {
newErr := GenericOpenAPIError{
body: localVarBody,
error: err.Error(),
}
return localVarReturnValue, localVarHTTPResponse, newErr
}
return localVarReturnValue, localVarHTTPResponse, nil
}
type ApiGetMeasurementSchemasRequest struct {
ctx _context.Context
ApiService BucketSchemasApi
bucketID string
org *string
orgID *string
name *string
}
func (r ApiGetMeasurementSchemasRequest) BucketID(bucketID string) ApiGetMeasurementSchemasRequest {
r.bucketID = bucketID
return r
}
func (r ApiGetMeasurementSchemasRequest) GetBucketID() string {
return r.bucketID
}
func (r ApiGetMeasurementSchemasRequest) Org(org string) ApiGetMeasurementSchemasRequest {
r.org = &org
return r
}
func (r ApiGetMeasurementSchemasRequest) GetOrg() *string {
return r.org
}
func (r ApiGetMeasurementSchemasRequest) OrgID(orgID string) ApiGetMeasurementSchemasRequest {
r.orgID = &orgID
return r
}
func (r ApiGetMeasurementSchemasRequest) GetOrgID() *string {
return r.orgID
}
func (r ApiGetMeasurementSchemasRequest) Name(name string) ApiGetMeasurementSchemasRequest {
r.name = &name
return r
}
func (r ApiGetMeasurementSchemasRequest) GetName() *string {
return r.name
}
func (r ApiGetMeasurementSchemasRequest) Execute() (MeasurementSchemaList, *_nethttp.Response, error) {
return r.ApiService.GetMeasurementSchemasExecute(r)
}
/*
* GetMeasurementSchemas Retrieve a list of measurement schemas defined for this bucket
* @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
* @param bucketID The ID of the bucket
* @return ApiGetMeasurementSchemasRequest
*/
func (a *BucketSchemasApiService) GetMeasurementSchemas(ctx _context.Context, bucketID string) ApiGetMeasurementSchemasRequest {
return ApiGetMeasurementSchemasRequest{
ApiService: a,
ctx: ctx,
bucketID: bucketID,
}
}
/*
* Execute executes the request
* @return MeasurementSchemaList
*/
func (a *BucketSchemasApiService) GetMeasurementSchemasExecute(r ApiGetMeasurementSchemasRequest) (MeasurementSchemaList, *_nethttp.Response, error) {
var (
localVarHTTPMethod = _nethttp.MethodGet
localVarPostBody interface{}
localVarFormFileName string
localVarFileName string
localVarFileBytes []byte
localVarReturnValue MeasurementSchemaList
)
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BucketSchemasApiService.GetMeasurementSchemas")
if err != nil {
return localVarReturnValue, nil, GenericOpenAPIError{error: err.Error()}
}
localVarPath := localBasePath + "/buckets/{bucketID}/schema/measurements"
localVarPath = strings.Replace(localVarPath, "{"+"bucketID"+"}", _neturl.PathEscape(parameterToString(r.bucketID, "")), -1)
localVarHeaderParams := make(map[string]string)
localVarQueryParams := _neturl.Values{}
localVarFormParams := _neturl.Values{}
if r.org != nil {
localVarQueryParams.Add("org", parameterToString(*r.org, ""))
}
if r.orgID != nil {
localVarQueryParams.Add("orgID", parameterToString(*r.orgID, ""))
}
if r.name != nil {
localVarQueryParams.Add("name", parameterToString(*r.name, ""))
}
// to determine the Content-Type header
localVarHTTPContentTypes := []string{}
// set Content-Type header
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
if localVarHTTPContentType != "" {
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
}
// to determine the Accept header
localVarHTTPHeaderAccepts := []string{"application/json"}
// set Accept header
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
if localVarHTTPHeaderAccept != "" {
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
}
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
if err != nil {
return localVarReturnValue, nil, err
}
localVarHTTPResponse, err := a.client.callAPI(req)
if err != nil || localVarHTTPResponse == nil {
return localVarReturnValue, localVarHTTPResponse, err
}
localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
localVarHTTPResponse.Body.Close()
localVarHTTPResponse.Body = _ioutil.NopCloser(bytes.NewBuffer(localVarBody))
if err != nil {
return localVarReturnValue, localVarHTTPResponse, err
}
if localVarHTTPResponse.StatusCode >= 300 {
newErr := GenericOpenAPIError{
body: localVarBody,
error: localVarHTTPResponse.Status,
}
if localVarHTTPResponse.StatusCode == 404 {
var v Error
err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
if err != nil {
newErr.error = err.Error()
return localVarReturnValue, localVarHTTPResponse, newErr
}
newErr.model = &v
}
return localVarReturnValue, localVarHTTPResponse, newErr
}
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
if err != nil {
newErr := GenericOpenAPIError{
body: localVarBody,
error: err.Error(),
}
return localVarReturnValue, localVarHTTPResponse, newErr
}
return localVarReturnValue, localVarHTTPResponse, nil
}
type ApiUpdateMeasurementSchemaRequest struct {
ctx _context.Context
ApiService BucketSchemasApi
bucketID string
measurementID string
org *string
orgID *string
measurementSchemaUpdateRequest *MeasurementSchemaUpdateRequest
}
func (r ApiUpdateMeasurementSchemaRequest) BucketID(bucketID string) ApiUpdateMeasurementSchemaRequest {
r.bucketID = bucketID
return r
}
func (r ApiUpdateMeasurementSchemaRequest) GetBucketID() string {
return r.bucketID
}
func (r ApiUpdateMeasurementSchemaRequest) MeasurementID(measurementID string) ApiUpdateMeasurementSchemaRequest {
r.measurementID = measurementID
return r
}
func (r ApiUpdateMeasurementSchemaRequest) GetMeasurementID() string {
return r.measurementID
}
func (r ApiUpdateMeasurementSchemaRequest) Org(org string) ApiUpdateMeasurementSchemaRequest {
r.org = &org
return r
}
func (r ApiUpdateMeasurementSchemaRequest) GetOrg() *string {
return r.org
}
func (r ApiUpdateMeasurementSchemaRequest) OrgID(orgID string) ApiUpdateMeasurementSchemaRequest {
r.orgID = &orgID
return r
}
func (r ApiUpdateMeasurementSchemaRequest) GetOrgID() *string {
return r.orgID
}
func (r ApiUpdateMeasurementSchemaRequest) MeasurementSchemaUpdateRequest(measurementSchemaUpdateRequest MeasurementSchemaUpdateRequest) ApiUpdateMeasurementSchemaRequest {
r.measurementSchemaUpdateRequest = &measurementSchemaUpdateRequest
return r
}
func (r ApiUpdateMeasurementSchemaRequest) GetMeasurementSchemaUpdateRequest() *MeasurementSchemaUpdateRequest {
return r.measurementSchemaUpdateRequest
}
func (r ApiUpdateMeasurementSchemaRequest) Execute() (MeasurementSchema, *_nethttp.Response, error) {
return r.ApiService.UpdateMeasurementSchemaExecute(r)
}
/*
* UpdateMeasurementSchema Update existing measurement schema
* @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
* @param bucketID The ID of the bucket
* @param measurementID The ID of the measurement
* @return ApiUpdateMeasurementSchemaRequest
*/
func (a *BucketSchemasApiService) UpdateMeasurementSchema(ctx _context.Context, bucketID string, measurementID string) ApiUpdateMeasurementSchemaRequest {
return ApiUpdateMeasurementSchemaRequest{
ApiService: a,
ctx: ctx,
bucketID: bucketID,
measurementID: measurementID,
}
}
/*
* Execute executes the request
* @return MeasurementSchema
*/
func (a *BucketSchemasApiService) UpdateMeasurementSchemaExecute(r ApiUpdateMeasurementSchemaRequest) (MeasurementSchema, *_nethttp.Response, error) {
var (
localVarHTTPMethod = _nethttp.MethodPatch
localVarPostBody interface{}
localVarFormFileName string
localVarFileName string
localVarFileBytes []byte
localVarReturnValue MeasurementSchema
)
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BucketSchemasApiService.UpdateMeasurementSchema")
if err != nil {
return localVarReturnValue, nil, GenericOpenAPIError{error: err.Error()}
}
localVarPath := localBasePath + "/buckets/{bucketID}/schema/measurements/{measurementID}"
localVarPath = strings.Replace(localVarPath, "{"+"bucketID"+"}", _neturl.PathEscape(parameterToString(r.bucketID, "")), -1)
localVarPath = strings.Replace(localVarPath, "{"+"measurementID"+"}", _neturl.PathEscape(parameterToString(r.measurementID, "")), -1)
localVarHeaderParams := make(map[string]string)
localVarQueryParams := _neturl.Values{}
localVarFormParams := _neturl.Values{}
if r.org != nil {
localVarQueryParams.Add("org", parameterToString(*r.org, ""))
}
if r.orgID != nil {
localVarQueryParams.Add("orgID", parameterToString(*r.orgID, ""))
}
// to determine the Content-Type header
localVarHTTPContentTypes := []string{"application/json"}
// set Content-Type header
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
if localVarHTTPContentType != "" {
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
}
// to determine the Accept header
localVarHTTPHeaderAccepts := []string{"application/json"}
// set Accept header
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
if localVarHTTPHeaderAccept != "" {
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
}
// body params
localVarPostBody = r.measurementSchemaUpdateRequest
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
if err != nil {
return localVarReturnValue, nil, err
}
localVarHTTPResponse, err := a.client.callAPI(req)
if err != nil || localVarHTTPResponse == nil {
return localVarReturnValue, localVarHTTPResponse, err
}
localVarBody, err := _ioutil.ReadAll(localVarHTTPResponse.Body)
localVarHTTPResponse.Body.Close()
localVarHTTPResponse.Body = _ioutil.NopCloser(bytes.NewBuffer(localVarBody))
if err != nil {
return localVarReturnValue, localVarHTTPResponse, err
}
if localVarHTTPResponse.StatusCode >= 300 {
newErr := GenericOpenAPIError{
body: localVarBody,
error: localVarHTTPResponse.Status,
}
if localVarHTTPResponse.StatusCode == 400 {
var v Error
err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
if err != nil {
newErr.error = err.Error()
return localVarReturnValue, localVarHTTPResponse, newErr
}
newErr.model = &v
}
return localVarReturnValue, localVarHTTPResponse, newErr
}
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
if err != nil {
newErr := GenericOpenAPIError{
body: localVarBody,
error: err.Error(),
}
return localVarReturnValue, localVarHTTPResponse, newErr
}
return localVarReturnValue, localVarHTTPResponse, nil
}

View File

@ -47,6 +47,8 @@ type APIClient struct {
// API Services
BucketSchemasApi BucketSchemasApi
BucketsApi BucketsApi
HealthApi HealthApi
@ -74,6 +76,7 @@ func NewAPIClient(cfg *Configuration) *APIClient {
c.common.client = c
// API Services
c.BucketSchemasApi = (*BucketSchemasApiService)(&c.common)
c.BucketsApi = (*BucketsApiService)(&c.common)
c.HealthApi = (*HealthApiService)(&c.common)
c.OrganizationsApi = (*OrganizationsApiService)(&c.common)

View File

@ -24,6 +24,7 @@ type Bucket struct {
Description *string `json:"description,omitempty"`
OrgID *string `json:"orgID,omitempty"`
Rp *string `json:"rp,omitempty"`
SchemaType *SchemaType `json:"schemaType,omitempty"`
CreatedAt *time.Time `json:"createdAt,omitempty"`
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
// Rules to expire or retain data. No rules means data never expires.
@ -270,6 +271,38 @@ func (o *Bucket) SetRp(v string) {
o.Rp = &v
}
// GetSchemaType returns the SchemaType field value if set, zero value otherwise.
func (o *Bucket) GetSchemaType() SchemaType {
if o == nil || o.SchemaType == nil {
var ret SchemaType
return ret
}
return *o.SchemaType
}
// GetSchemaTypeOk returns a tuple with the SchemaType field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *Bucket) GetSchemaTypeOk() (*SchemaType, bool) {
if o == nil || o.SchemaType == nil {
return nil, false
}
return o.SchemaType, true
}
// HasSchemaType returns a boolean if a field has been set.
func (o *Bucket) HasSchemaType() bool {
if o != nil && o.SchemaType != nil {
return true
}
return false
}
// SetSchemaType gets a reference to the given SchemaType and assigns it to the SchemaType field.
func (o *Bucket) SetSchemaType(v SchemaType) {
o.SchemaType = &v
}
// GetCreatedAt returns the CreatedAt field value if set, zero value otherwise.
func (o *Bucket) GetCreatedAt() time.Time {
if o == nil || o.CreatedAt == nil {
@ -413,6 +446,9 @@ func (o Bucket) MarshalJSON() ([]byte, error) {
if o.Rp != nil {
toSerialize["rp"] = o.Rp
}
if o.SchemaType != nil {
toSerialize["schemaType"] = o.SchemaType
}
if o.CreatedAt != nil {
toSerialize["createdAt"] = o.CreatedAt
}

View File

@ -0,0 +1,86 @@
/*
* Subset of Influx API covered by Influx CLI
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 2.0.0
*/
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
package api
import (
"encoding/json"
"fmt"
)
// ColumnDataType the model 'ColumnDataType'
type ColumnDataType string
// List of ColumnDataType
const (
COLUMNDATATYPE_INTEGER ColumnDataType = "integer"
COLUMNDATATYPE_FLOAT ColumnDataType = "float"
COLUMNDATATYPE_BOOLEAN ColumnDataType = "boolean"
COLUMNDATATYPE_STRING ColumnDataType = "string"
COLUMNDATATYPE_UNSIGNED ColumnDataType = "unsigned"
)
func (v *ColumnDataType) UnmarshalJSON(src []byte) error {
var value string
err := json.Unmarshal(src, &value)
if err != nil {
return err
}
enumTypeValue := ColumnDataType(value)
for _, existing := range []ColumnDataType{"integer", "float", "boolean", "string", "unsigned"} {
if existing == enumTypeValue {
*v = enumTypeValue
return nil
}
}
return fmt.Errorf("%+v is not a valid ColumnDataType", value)
}
// Ptr returns reference to ColumnDataType value
func (v ColumnDataType) Ptr() *ColumnDataType {
return &v
}
type NullableColumnDataType struct {
value *ColumnDataType
isSet bool
}
func (v NullableColumnDataType) Get() *ColumnDataType {
return v.value
}
func (v *NullableColumnDataType) Set(val *ColumnDataType) {
v.value = val
v.isSet = true
}
func (v NullableColumnDataType) IsSet() bool {
return v.isSet
}
func (v *NullableColumnDataType) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableColumnDataType(val *ColumnDataType) *NullableColumnDataType {
return &NullableColumnDataType{value: val, isSet: true}
}
func (v NullableColumnDataType) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableColumnDataType) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -0,0 +1,84 @@
/*
* Subset of Influx API covered by Influx CLI
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 2.0.0
*/
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
package api
import (
"encoding/json"
"fmt"
)
// ColumnSemanticType the model 'ColumnSemanticType'
type ColumnSemanticType string
// List of ColumnSemanticType
const (
COLUMNSEMANTICTYPE_TIMESTAMP ColumnSemanticType = "timestamp"
COLUMNSEMANTICTYPE_TAG ColumnSemanticType = "tag"
COLUMNSEMANTICTYPE_FIELD ColumnSemanticType = "field"
)
func (v *ColumnSemanticType) UnmarshalJSON(src []byte) error {
var value string
err := json.Unmarshal(src, &value)
if err != nil {
return err
}
enumTypeValue := ColumnSemanticType(value)
for _, existing := range []ColumnSemanticType{"timestamp", "tag", "field"} {
if existing == enumTypeValue {
*v = enumTypeValue
return nil
}
}
return fmt.Errorf("%+v is not a valid ColumnSemanticType", value)
}
// Ptr returns reference to ColumnSemanticType value
func (v ColumnSemanticType) Ptr() *ColumnSemanticType {
return &v
}
type NullableColumnSemanticType struct {
value *ColumnSemanticType
isSet bool
}
func (v NullableColumnSemanticType) Get() *ColumnSemanticType {
return v.value
}
func (v *NullableColumnSemanticType) Set(val *ColumnSemanticType) {
v.value = val
v.isSet = true
}
func (v NullableColumnSemanticType) IsSet() bool {
return v.isSet
}
func (v *NullableColumnSemanticType) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableColumnSemanticType(val *ColumnSemanticType) *NullableColumnSemanticType {
return &NullableColumnSemanticType{value: val, isSet: true}
}
func (v NullableColumnSemanticType) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableColumnSemanticType) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -0,0 +1,224 @@
/*
* Subset of Influx API covered by Influx CLI
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 2.0.0
*/
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
package api
import (
"encoding/json"
"time"
)
// MeasurementSchema The schema definition for a single measurement
type MeasurementSchema struct {
Id string `json:"id"`
Name string `json:"name"`
// An ordered collection of column definitions
Columns []MeasurementSchemaColumn `json:"columns"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
// NewMeasurementSchema instantiates a new MeasurementSchema object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewMeasurementSchema(id string, name string, columns []MeasurementSchemaColumn, createdAt time.Time, updatedAt time.Time) *MeasurementSchema {
this := MeasurementSchema{}
this.Id = id
this.Name = name
this.Columns = columns
this.CreatedAt = createdAt
this.UpdatedAt = updatedAt
return &this
}
// NewMeasurementSchemaWithDefaults instantiates a new MeasurementSchema object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewMeasurementSchemaWithDefaults() *MeasurementSchema {
this := MeasurementSchema{}
return &this
}
// GetId returns the Id field value
func (o *MeasurementSchema) GetId() string {
if o == nil {
var ret string
return ret
}
return o.Id
}
// GetIdOk returns a tuple with the Id field value
// and a boolean to check if the value has been set.
func (o *MeasurementSchema) GetIdOk() (*string, bool) {
if o == nil {
return nil, false
}
return &o.Id, true
}
// SetId sets field value
func (o *MeasurementSchema) SetId(v string) {
o.Id = v
}
// GetName returns the Name field value
func (o *MeasurementSchema) GetName() string {
if o == nil {
var ret string
return ret
}
return o.Name
}
// GetNameOk returns a tuple with the Name field value
// and a boolean to check if the value has been set.
func (o *MeasurementSchema) GetNameOk() (*string, bool) {
if o == nil {
return nil, false
}
return &o.Name, true
}
// SetName sets field value
func (o *MeasurementSchema) SetName(v string) {
o.Name = v
}
// GetColumns returns the Columns field value
func (o *MeasurementSchema) GetColumns() []MeasurementSchemaColumn {
if o == nil {
var ret []MeasurementSchemaColumn
return ret
}
return o.Columns
}
// GetColumnsOk returns a tuple with the Columns field value
// and a boolean to check if the value has been set.
func (o *MeasurementSchema) GetColumnsOk() (*[]MeasurementSchemaColumn, bool) {
if o == nil {
return nil, false
}
return &o.Columns, true
}
// SetColumns sets field value
func (o *MeasurementSchema) SetColumns(v []MeasurementSchemaColumn) {
o.Columns = v
}
// GetCreatedAt returns the CreatedAt field value
func (o *MeasurementSchema) GetCreatedAt() time.Time {
if o == nil {
var ret time.Time
return ret
}
return o.CreatedAt
}
// GetCreatedAtOk returns a tuple with the CreatedAt field value
// and a boolean to check if the value has been set.
func (o *MeasurementSchema) GetCreatedAtOk() (*time.Time, bool) {
if o == nil {
return nil, false
}
return &o.CreatedAt, true
}
// SetCreatedAt sets field value
func (o *MeasurementSchema) SetCreatedAt(v time.Time) {
o.CreatedAt = v
}
// GetUpdatedAt returns the UpdatedAt field value
func (o *MeasurementSchema) GetUpdatedAt() time.Time {
if o == nil {
var ret time.Time
return ret
}
return o.UpdatedAt
}
// GetUpdatedAtOk returns a tuple with the UpdatedAt field value
// and a boolean to check if the value has been set.
func (o *MeasurementSchema) GetUpdatedAtOk() (*time.Time, bool) {
if o == nil {
return nil, false
}
return &o.UpdatedAt, true
}
// SetUpdatedAt sets field value
func (o *MeasurementSchema) SetUpdatedAt(v time.Time) {
o.UpdatedAt = v
}
func (o MeasurementSchema) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
if true {
toSerialize["id"] = o.Id
}
if true {
toSerialize["name"] = o.Name
}
if true {
toSerialize["columns"] = o.Columns
}
if true {
toSerialize["createdAt"] = o.CreatedAt
}
if true {
toSerialize["updatedAt"] = o.UpdatedAt
}
return json.Marshal(toSerialize)
}
type NullableMeasurementSchema struct {
value *MeasurementSchema
isSet bool
}
func (v NullableMeasurementSchema) Get() *MeasurementSchema {
return v.value
}
func (v *NullableMeasurementSchema) Set(val *MeasurementSchema) {
v.value = val
v.isSet = true
}
func (v NullableMeasurementSchema) IsSet() bool {
return v.isSet
}
func (v *NullableMeasurementSchema) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableMeasurementSchema(val *MeasurementSchema) *NullableMeasurementSchema {
return &NullableMeasurementSchema{value: val, isSet: true}
}
func (v NullableMeasurementSchema) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableMeasurementSchema) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -0,0 +1,171 @@
/*
* Subset of Influx API covered by Influx CLI
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 2.0.0
*/
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
package api
import (
"encoding/json"
)
// MeasurementSchemaColumn Definition of a measurement column
type MeasurementSchemaColumn struct {
Name string `json:"name"`
Type ColumnSemanticType `json:"type"`
DataType *ColumnDataType `json:"dataType,omitempty"`
}
// NewMeasurementSchemaColumn instantiates a new MeasurementSchemaColumn object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewMeasurementSchemaColumn(name string, type_ ColumnSemanticType) *MeasurementSchemaColumn {
this := MeasurementSchemaColumn{}
this.Name = name
this.Type = type_
return &this
}
// NewMeasurementSchemaColumnWithDefaults instantiates a new MeasurementSchemaColumn object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewMeasurementSchemaColumnWithDefaults() *MeasurementSchemaColumn {
this := MeasurementSchemaColumn{}
return &this
}
// GetName returns the Name field value
func (o *MeasurementSchemaColumn) GetName() string {
if o == nil {
var ret string
return ret
}
return o.Name
}
// GetNameOk returns a tuple with the Name field value
// and a boolean to check if the value has been set.
func (o *MeasurementSchemaColumn) GetNameOk() (*string, bool) {
if o == nil {
return nil, false
}
return &o.Name, true
}
// SetName sets field value
func (o *MeasurementSchemaColumn) SetName(v string) {
o.Name = v
}
// GetType returns the Type field value
func (o *MeasurementSchemaColumn) GetType() ColumnSemanticType {
if o == nil {
var ret ColumnSemanticType
return ret
}
return o.Type
}
// GetTypeOk returns a tuple with the Type field value
// and a boolean to check if the value has been set.
func (o *MeasurementSchemaColumn) GetTypeOk() (*ColumnSemanticType, bool) {
if o == nil {
return nil, false
}
return &o.Type, true
}
// SetType sets field value
func (o *MeasurementSchemaColumn) SetType(v ColumnSemanticType) {
o.Type = v
}
// GetDataType returns the DataType field value if set, zero value otherwise.
func (o *MeasurementSchemaColumn) GetDataType() ColumnDataType {
if o == nil || o.DataType == nil {
var ret ColumnDataType
return ret
}
return *o.DataType
}
// GetDataTypeOk returns a tuple with the DataType field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *MeasurementSchemaColumn) GetDataTypeOk() (*ColumnDataType, bool) {
if o == nil || o.DataType == nil {
return nil, false
}
return o.DataType, true
}
// HasDataType returns a boolean if a field has been set.
func (o *MeasurementSchemaColumn) HasDataType() bool {
if o != nil && o.DataType != nil {
return true
}
return false
}
// SetDataType gets a reference to the given ColumnDataType and assigns it to the DataType field.
func (o *MeasurementSchemaColumn) SetDataType(v ColumnDataType) {
o.DataType = &v
}
func (o MeasurementSchemaColumn) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
if true {
toSerialize["name"] = o.Name
}
if true {
toSerialize["type"] = o.Type
}
if o.DataType != nil {
toSerialize["dataType"] = o.DataType
}
return json.Marshal(toSerialize)
}
type NullableMeasurementSchemaColumn struct {
value *MeasurementSchemaColumn
isSet bool
}
func (v NullableMeasurementSchemaColumn) Get() *MeasurementSchemaColumn {
return v.value
}
func (v *NullableMeasurementSchemaColumn) Set(val *MeasurementSchemaColumn) {
v.value = val
v.isSet = true
}
func (v NullableMeasurementSchemaColumn) IsSet() bool {
return v.isSet
}
func (v *NullableMeasurementSchemaColumn) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableMeasurementSchemaColumn(val *MeasurementSchemaColumn) *NullableMeasurementSchemaColumn {
return &NullableMeasurementSchemaColumn{value: val, isSet: true}
}
func (v NullableMeasurementSchemaColumn) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableMeasurementSchemaColumn) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -0,0 +1,136 @@
/*
* Subset of Influx API covered by Influx CLI
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 2.0.0
*/
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
package api
import (
"encoding/json"
)
// MeasurementSchemaCreateRequest Create a new measurement schema
type MeasurementSchemaCreateRequest struct {
Name string `json:"name"`
// An ordered collection of column definitions
Columns []MeasurementSchemaColumn `json:"columns"`
}
// NewMeasurementSchemaCreateRequest instantiates a new MeasurementSchemaCreateRequest object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewMeasurementSchemaCreateRequest(name string, columns []MeasurementSchemaColumn) *MeasurementSchemaCreateRequest {
this := MeasurementSchemaCreateRequest{}
this.Name = name
this.Columns = columns
return &this
}
// NewMeasurementSchemaCreateRequestWithDefaults instantiates a new MeasurementSchemaCreateRequest object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewMeasurementSchemaCreateRequestWithDefaults() *MeasurementSchemaCreateRequest {
this := MeasurementSchemaCreateRequest{}
return &this
}
// GetName returns the Name field value
func (o *MeasurementSchemaCreateRequest) GetName() string {
if o == nil {
var ret string
return ret
}
return o.Name
}
// GetNameOk returns a tuple with the Name field value
// and a boolean to check if the value has been set.
func (o *MeasurementSchemaCreateRequest) GetNameOk() (*string, bool) {
if o == nil {
return nil, false
}
return &o.Name, true
}
// SetName sets field value
func (o *MeasurementSchemaCreateRequest) SetName(v string) {
o.Name = v
}
// GetColumns returns the Columns field value
func (o *MeasurementSchemaCreateRequest) GetColumns() []MeasurementSchemaColumn {
if o == nil {
var ret []MeasurementSchemaColumn
return ret
}
return o.Columns
}
// GetColumnsOk returns a tuple with the Columns field value
// and a boolean to check if the value has been set.
func (o *MeasurementSchemaCreateRequest) GetColumnsOk() (*[]MeasurementSchemaColumn, bool) {
if o == nil {
return nil, false
}
return &o.Columns, true
}
// SetColumns sets field value
func (o *MeasurementSchemaCreateRequest) SetColumns(v []MeasurementSchemaColumn) {
o.Columns = v
}
func (o MeasurementSchemaCreateRequest) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
if true {
toSerialize["name"] = o.Name
}
if true {
toSerialize["columns"] = o.Columns
}
return json.Marshal(toSerialize)
}
type NullableMeasurementSchemaCreateRequest struct {
value *MeasurementSchemaCreateRequest
isSet bool
}
func (v NullableMeasurementSchemaCreateRequest) Get() *MeasurementSchemaCreateRequest {
return v.value
}
func (v *NullableMeasurementSchemaCreateRequest) Set(val *MeasurementSchemaCreateRequest) {
v.value = val
v.isSet = true
}
func (v NullableMeasurementSchemaCreateRequest) IsSet() bool {
return v.isSet
}
func (v *NullableMeasurementSchemaCreateRequest) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableMeasurementSchemaCreateRequest(val *MeasurementSchemaCreateRequest) *NullableMeasurementSchemaCreateRequest {
return &NullableMeasurementSchemaCreateRequest{value: val, isSet: true}
}
func (v NullableMeasurementSchemaCreateRequest) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableMeasurementSchemaCreateRequest) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -0,0 +1,106 @@
/*
* Subset of Influx API covered by Influx CLI
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 2.0.0
*/
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
package api
import (
"encoding/json"
)
// MeasurementSchemaList A list of measurement schemas returning summary information
type MeasurementSchemaList struct {
MeasurementSchemas []MeasurementSchema `json:"measurementSchemas"`
}
// NewMeasurementSchemaList instantiates a new MeasurementSchemaList object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewMeasurementSchemaList(measurementSchemas []MeasurementSchema) *MeasurementSchemaList {
this := MeasurementSchemaList{}
this.MeasurementSchemas = measurementSchemas
return &this
}
// NewMeasurementSchemaListWithDefaults instantiates a new MeasurementSchemaList object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewMeasurementSchemaListWithDefaults() *MeasurementSchemaList {
this := MeasurementSchemaList{}
return &this
}
// GetMeasurementSchemas returns the MeasurementSchemas field value
func (o *MeasurementSchemaList) GetMeasurementSchemas() []MeasurementSchema {
if o == nil {
var ret []MeasurementSchema
return ret
}
return o.MeasurementSchemas
}
// GetMeasurementSchemasOk returns a tuple with the MeasurementSchemas field value
// and a boolean to check if the value has been set.
func (o *MeasurementSchemaList) GetMeasurementSchemasOk() (*[]MeasurementSchema, bool) {
if o == nil {
return nil, false
}
return &o.MeasurementSchemas, true
}
// SetMeasurementSchemas sets field value
func (o *MeasurementSchemaList) SetMeasurementSchemas(v []MeasurementSchema) {
o.MeasurementSchemas = v
}
func (o MeasurementSchemaList) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
if true {
toSerialize["measurementSchemas"] = o.MeasurementSchemas
}
return json.Marshal(toSerialize)
}
type NullableMeasurementSchemaList struct {
value *MeasurementSchemaList
isSet bool
}
func (v NullableMeasurementSchemaList) Get() *MeasurementSchemaList {
return v.value
}
func (v *NullableMeasurementSchemaList) Set(val *MeasurementSchemaList) {
v.value = val
v.isSet = true
}
func (v NullableMeasurementSchemaList) IsSet() bool {
return v.isSet
}
func (v *NullableMeasurementSchemaList) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableMeasurementSchemaList(val *MeasurementSchemaList) *NullableMeasurementSchemaList {
return &NullableMeasurementSchemaList{value: val, isSet: true}
}
func (v NullableMeasurementSchemaList) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableMeasurementSchemaList) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -0,0 +1,107 @@
/*
* Subset of Influx API covered by Influx CLI
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 2.0.0
*/
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
package api
import (
"encoding/json"
)
// MeasurementSchemaUpdateRequest Update an existing measurement schema
type MeasurementSchemaUpdateRequest struct {
// An ordered collection of column definitions
Columns []MeasurementSchemaColumn `json:"columns"`
}
// NewMeasurementSchemaUpdateRequest instantiates a new MeasurementSchemaUpdateRequest object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewMeasurementSchemaUpdateRequest(columns []MeasurementSchemaColumn) *MeasurementSchemaUpdateRequest {
this := MeasurementSchemaUpdateRequest{}
this.Columns = columns
return &this
}
// NewMeasurementSchemaUpdateRequestWithDefaults instantiates a new MeasurementSchemaUpdateRequest object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewMeasurementSchemaUpdateRequestWithDefaults() *MeasurementSchemaUpdateRequest {
this := MeasurementSchemaUpdateRequest{}
return &this
}
// GetColumns returns the Columns field value
func (o *MeasurementSchemaUpdateRequest) GetColumns() []MeasurementSchemaColumn {
if o == nil {
var ret []MeasurementSchemaColumn
return ret
}
return o.Columns
}
// GetColumnsOk returns a tuple with the Columns field value
// and a boolean to check if the value has been set.
func (o *MeasurementSchemaUpdateRequest) GetColumnsOk() (*[]MeasurementSchemaColumn, bool) {
if o == nil {
return nil, false
}
return &o.Columns, true
}
// SetColumns sets field value
func (o *MeasurementSchemaUpdateRequest) SetColumns(v []MeasurementSchemaColumn) {
o.Columns = v
}
func (o MeasurementSchemaUpdateRequest) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
if true {
toSerialize["columns"] = o.Columns
}
return json.Marshal(toSerialize)
}
type NullableMeasurementSchemaUpdateRequest struct {
value *MeasurementSchemaUpdateRequest
isSet bool
}
func (v NullableMeasurementSchemaUpdateRequest) Get() *MeasurementSchemaUpdateRequest {
return v.value
}
func (v *NullableMeasurementSchemaUpdateRequest) Set(val *MeasurementSchemaUpdateRequest) {
v.value = val
v.isSet = true
}
func (v NullableMeasurementSchemaUpdateRequest) IsSet() bool {
return v.isSet
}
func (v *NullableMeasurementSchemaUpdateRequest) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableMeasurementSchemaUpdateRequest(val *MeasurementSchemaUpdateRequest) *NullableMeasurementSchemaUpdateRequest {
return &NullableMeasurementSchemaUpdateRequest{value: val, isSet: true}
}
func (v NullableMeasurementSchemaUpdateRequest) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableMeasurementSchemaUpdateRequest) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -22,6 +22,7 @@ type PostBucketRequest struct {
Rp *string `json:"rp,omitempty"`
// Rules to expire or retain data. No rules means data never expires.
RetentionRules []RetentionRule `json:"retentionRules"`
SchemaType *SchemaType `json:"schemaType,omitempty"`
}
// NewPostBucketRequest instantiates a new PostBucketRequest object
@ -180,6 +181,38 @@ func (o *PostBucketRequest) SetRetentionRules(v []RetentionRule) {
o.RetentionRules = v
}
// GetSchemaType returns the SchemaType field value if set, zero value otherwise.
func (o *PostBucketRequest) GetSchemaType() SchemaType {
if o == nil || o.SchemaType == nil {
var ret SchemaType
return ret
}
return *o.SchemaType
}
// GetSchemaTypeOk returns a tuple with the SchemaType field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *PostBucketRequest) GetSchemaTypeOk() (*SchemaType, bool) {
if o == nil || o.SchemaType == nil {
return nil, false
}
return o.SchemaType, true
}
// HasSchemaType returns a boolean if a field has been set.
func (o *PostBucketRequest) HasSchemaType() bool {
if o != nil && o.SchemaType != nil {
return true
}
return false
}
// SetSchemaType gets a reference to the given SchemaType and assigns it to the SchemaType field.
func (o *PostBucketRequest) SetSchemaType(v SchemaType) {
o.SchemaType = &v
}
func (o PostBucketRequest) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
if true {
@ -197,6 +230,9 @@ func (o PostBucketRequest) MarshalJSON() ([]byte, error) {
if true {
toSerialize["retentionRules"] = o.RetentionRules
}
if o.SchemaType != nil {
toSerialize["schemaType"] = o.SchemaType
}
return json.Marshal(toSerialize)
}

View File

@ -0,0 +1,83 @@
/*
* Subset of Influx API covered by Influx CLI
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* API version: 2.0.0
*/
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
package api
import (
"encoding/json"
"fmt"
)
// SchemaType the model 'SchemaType'
type SchemaType string
// List of SchemaType
const (
SCHEMATYPE_IMPLICIT SchemaType = "implicit"
SCHEMATYPE_EXPLICIT SchemaType = "explicit"
)
func (v *SchemaType) UnmarshalJSON(src []byte) error {
var value string
err := json.Unmarshal(src, &value)
if err != nil {
return err
}
enumTypeValue := SchemaType(value)
for _, existing := range []SchemaType{"implicit", "explicit"} {
if existing == enumTypeValue {
*v = enumTypeValue
return nil
}
}
return fmt.Errorf("%+v is not a valid SchemaType", value)
}
// Ptr returns reference to SchemaType value
func (v SchemaType) Ptr() *SchemaType {
return &v
}
type NullableSchemaType struct {
value *SchemaType
isSet bool
}
func (v NullableSchemaType) Get() *SchemaType {
return v.value
}
func (v *NullableSchemaType) Set(val *SchemaType) {
v.value = val
v.isSet = true
}
func (v NullableSchemaType) IsSet() bool {
return v.isSet
}
func (v *NullableSchemaType) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableSchemaType(val *SchemaType) *NullableSchemaType {
return &NullableSchemaType{value: val, isSet: true}
}
func (v NullableSchemaType) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableSchemaType) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -0,0 +1,23 @@
package api
import (
"fmt"
)
func (v SchemaType) String() string {
return string(v)
}
// Set implements the cli.Generic interface for parsing
// flags.
func (v *SchemaType) Set(s string) error {
switch s {
case string(SCHEMATYPE_IMPLICIT):
*v = SCHEMATYPE_IMPLICIT
case string(SCHEMATYPE_EXPLICIT):
*v = SCHEMATYPE_EXPLICIT
default:
return fmt.Errorf("unsupported schema type: %q", s)
}
return nil
}

View File

@ -0,0 +1,39 @@
package api
import (
"fmt"
"strings"
)
// UnmarshalCSV implements the gocsv.TypeUnmarshaller interface
// for decoding CSV.
func (v *ColumnSemanticType) UnmarshalCSV(s string) error {
types := []string{string(COLUMNSEMANTICTYPE_TIMESTAMP), string(COLUMNSEMANTICTYPE_TAG), string(COLUMNSEMANTICTYPE_FIELD)}
for _, t := range types {
if s == t {
*v = ColumnSemanticType(t)
return nil
}
}
return fmt.Errorf("%q is not a valid column type. Valid values are [%s]", s, strings.Join(types, ", "))
}
// UnmarshalCSV implements the gocsv.TypeUnmarshaller interface
// for decoding CSV.
func (v *ColumnDataType) UnmarshalCSV(s string) error {
types := []string{
string(COLUMNDATATYPE_INTEGER),
string(COLUMNDATATYPE_FLOAT),
string(COLUMNDATATYPE_BOOLEAN),
string(COLUMNDATATYPE_STRING),
string(COLUMNDATATYPE_UNSIGNED),
}
for _, t := range types {
if s == t {
*v = ColumnDataType(t)
return nil
}
}
return fmt.Errorf("%q is not a valid column data type. Valid values are [%s]", s, strings.Join(types, ", "))
}

View File

@ -24,6 +24,7 @@ type BucketsCreateParams struct {
Description string
Retention string
ShardGroupDuration string
SchemaType api.SchemaType
}
var (
@ -50,6 +51,7 @@ func (c *CLI) BucketsCreate(ctx context.Context, clients *BucketsClients, params
OrgID: params.OrgID,
Name: params.Name,
RetentionRules: []api.RetentionRule{},
SchemaType: &params.SchemaType,
}
if params.Description != "" {
reqBody.Description = &params.Description
@ -249,7 +251,7 @@ func (c *CLI) printBuckets(options bucketPrintOptions) error {
return c.PrintJSON(v)
}
headers := []string{"ID", "Name", "Retention", "Shard group duration", "Organization ID"}
headers := []string{"ID", "Name", "Retention", "Shard group duration", "Organization ID", "Schema Type"}
if options.deleted {
headers = append(headers, "Deleted")
}
@ -279,12 +281,19 @@ func (c *CLI) printBuckets(options bucketPrintOptions) error {
sgDur = "n/a"
}
schemaType := bkt.GetSchemaType()
if schemaType == "" {
// schemaType will be empty when querying OSS.
schemaType = api.SCHEMATYPE_IMPLICIT
}
row := map[string]interface{}{
"ID": bkt.GetId(),
"Name": bkt.GetName(),
"Retention": rp,
"Shard group duration": sgDur,
"Organization ID": bkt.GetOrgID(),
"Schema Type": schemaType,
}
if options.deleted {
row["Deleted"] = true

View File

@ -94,9 +94,9 @@ func TestBucketsCreate(t *testing.T) {
{
name: "retention but not shard-group duration",
params: internal.BucketsCreateParams{
OrgID: "123",
Name: "my-bucket",
Retention: "24h",
OrgID: "123",
Name: "my-bucket",
Retention: "24h",
},
buildOrgLookupFn: func(t *testing.T) func(api.ApiGetOrgsRequest) (api.Organizations, *http.Response, error) {
return func(api.ApiGetOrgsRequest) (api.Organizations, *http.Response, error) {
@ -123,6 +123,38 @@ func TestBucketsCreate(t *testing.T) {
}
},
},
{
name: "create bucket with explicit schema",
params: internal.BucketsCreateParams{
OrgID: "123",
Name: "my-bucket",
Retention: "24h",
SchemaType: api.SCHEMATYPE_EXPLICIT,
},
buildOrgLookupFn: func(t *testing.T) func(api.ApiGetOrgsRequest) (api.Organizations, *http.Response, error) {
return func(api.ApiGetOrgsRequest) (api.Organizations, *http.Response, error) {
return api.Organizations{}, nil, errors.New("unexpected org lookup call")
}
},
buildBucketCreateFn: func(t *testing.T) func(api.ApiPostBucketsRequest) (api.Bucket, *http.Response, error) {
return func(req api.ApiPostBucketsRequest) (api.Bucket, *http.Response, error) {
body := req.GetPostBucketRequest()
require.NotNil(t, body)
require.Equal(t, "123", body.OrgID)
require.NotNil(t, body.SchemaType)
assert.Equal(t, api.SCHEMATYPE_EXPLICIT, *body.SchemaType)
return api.Bucket{
Id: api.PtrString("456"),
OrgID: api.PtrString("123"),
Name: "my-bucket",
RetentionRules: body.RetentionRules,
SchemaType: api.SCHEMATYPE_EXPLICIT.Ptr(),
}, nil, nil
}
},
expectedStdoutPattern: `456\s+my-bucket\s+24h0m0s\s+n/a\s+123\s+explicit`,
},
{
name: "look up org by name",
params: internal.BucketsCreateParams{
@ -403,6 +435,56 @@ func TestBucketsList(t *testing.T) {
"999\\s+bucket2\\s+infinite\\s+1m0s\\s+456",
},
},
{
name: "list multiple bucket schema types",
params: internal.BucketsListParams{
OrgName: "my-org",
},
configOrgName: "my-default-org",
buildBucketLookupFn: func(t *testing.T) func(api.ApiGetBucketsRequest) (api.Buckets, *http.Response, error) {
return func(req api.ApiGetBucketsRequest) (api.Buckets, *http.Response, error) {
require.Equal(t, "my-org", *req.GetOrg())
require.Nil(t, req.GetId())
require.Nil(t, req.GetName())
require.Nil(t, req.GetOrgID())
return api.Buckets{
Buckets: &[]api.Bucket{
{
Id: api.PtrString("001"),
Name: "omit-schema-type",
OrgID: api.PtrString("456"),
RetentionRules: []api.RetentionRule{
{EverySeconds: 3600},
},
},
{
Id: api.PtrString("002"),
Name: "implicit-schema-type",
OrgID: api.PtrString("456"),
RetentionRules: []api.RetentionRule{
{EverySeconds: 3600},
},
SchemaType: api.SCHEMATYPE_IMPLICIT.Ptr(),
},
{
Id: api.PtrString("003"),
Name: "explicit-schema-type",
OrgID: api.PtrString("456"),
RetentionRules: []api.RetentionRule{
{EverySeconds: 3600},
},
SchemaType: api.SCHEMATYPE_EXPLICIT.Ptr(),
},
},
}, nil, nil
}
},
expectedStdoutPatterns: []string{
`001\s+omit-schema-type\s+1h0m0s\s+n/a\s+456\s+implicit`,
`002\s+implicit-schema-type\s+1h0m0s\s+n/a\s+456\s+implicit`,
`003\s+explicit-schema-type\s+1h0m0s\s+n/a\s+456\s+explicit`,
},
},
{
name: "no org specified",
expectedInErr: "must specify org ID or org name",
@ -631,7 +713,7 @@ func TestBucketsDelete(t *testing.T) {
return nil, nil
}
},
expectedStdoutPattern: "123\\s+my-bucket\\s+1h0m0s\\s+n/a\\s+456",
expectedStdoutPattern: "123\\s+my-bucket\\s+1h0m0s\\s+n/a\\s+456\\s+implicit",
},
{
name: "by name and org ID",
@ -667,7 +749,7 @@ func TestBucketsDelete(t *testing.T) {
return nil, nil
}
},
expectedStdoutPattern: "123\\s+my-bucket\\s+1h0m0s\\s+n/a\\s+456",
expectedStdoutPattern: "123\\s+my-bucket\\s+1h0m0s\\s+n/a\\s+456\\s+implicit",
},
{
name: "by name and org name",
@ -703,7 +785,7 @@ func TestBucketsDelete(t *testing.T) {
return nil, nil
}
},
expectedStdoutPattern: "123\\s+my-bucket\\s+1h0m0s\\s+n/a\\s+456",
expectedStdoutPattern: "123\\s+my-bucket\\s+1h0m0s\\s+n/a\\s+456\\s+implicit",
},
{
name: "by name in default org",
@ -738,7 +820,7 @@ func TestBucketsDelete(t *testing.T) {
return nil, nil
}
},
expectedStdoutPattern: "123\\s+my-bucket\\s+1h0m0s\\s+n/a\\s+456",
expectedStdoutPattern: "123\\s+my-bucket\\s+1h0m0s\\s+n/a\\s+456\\s+implicit",
},
{
name: "by name without org",
@ -800,7 +882,7 @@ func TestBucketsDelete(t *testing.T) {
if outLines[len(outLines)-1] == "" {
outLines = outLines[:len(outLines)-1]
}
require.Regexp(t, "ID\\s+Name\\s+Retention\\s+Shard group duration\\s+Organization ID\\s+Deleted", outLines[0])
require.Regexp(t, `ID\s+Name\s+Retention\s+Shard group duration\s+Organization ID\s+Schema Type\s+Deleted`, outLines[0])
require.Regexp(t, tc.expectedStdoutPattern+"\\s+true", outLines[1])
})
}

View File

@ -0,0 +1,294 @@
package bucket_schema
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"os"
"github.com/influxdata/influx-cli/v2/internal"
"github.com/influxdata/influx-cli/v2/internal/api"
)
type Client struct {
BucketApi api.BucketsApi
BucketSchemasApi api.BucketSchemasApi
CLI *internal.CLI
}
type orgBucketID struct {
OrgID string
BucketID string
}
func (c Client) resolveMeasurement(ctx context.Context, ids orgBucketID, name string) (string, error) {
res, _, err := c.BucketSchemasApi.
GetMeasurementSchemas(ctx, ids.BucketID).
OrgID(ids.OrgID).
Name(name).
Execute()
if err != nil {
return "", fmt.Errorf("failed to find measurement schema: %w", err)
}
if len(res.MeasurementSchemas) == 0 {
return "", fmt.Errorf("measurement schema %q not found", name)
}
return res.MeasurementSchemas[0].Id, nil
}
func (c Client) resolveOrgBucketIds(ctx context.Context, params internal.OrgBucketParams) (*orgBucketID, error) {
if params.OrgID.Valid() && params.BucketID.Valid() {
return &orgBucketID{OrgID: params.OrgID.String(), BucketID: params.BucketID.String()}, nil
}
if params.BucketName == "" {
return nil, errors.New("bucket missing: specify bucket ID or bucket name")
}
if !params.OrgID.Valid() && params.OrgName == "" && c.CLI.ActiveConfig.Org == "" {
return nil, errors.New("org missing: specify org ID or org name")
}
req := c.BucketApi.GetBuckets(ctx).Name(params.BucketName)
if params.OrgID.Valid() {
req = req.OrgID(params.OrgID.String())
} else if params.OrgName != "" {
req = req.Org(params.OrgName)
} else {
req = req.Org(c.CLI.ActiveConfig.Org)
}
resp, _, err := req.Execute()
if err != nil {
return nil, fmt.Errorf("failed to find bucket %q: %w", params.BucketName, err)
}
buckets := resp.GetBuckets()
if len(buckets) == 0 {
return nil, fmt.Errorf("bucket %q not found", params.BucketName)
}
return &orgBucketID{OrgID: buckets[0].GetOrgID(), BucketID: buckets[0].GetId()}, nil
}
func (c Client) readColumns(stdin io.Reader, f ColumnsFormat, path string) ([]api.MeasurementSchemaColumn, error) {
var (
r io.Reader
name string
)
if path == "" {
r = stdin
name = "stdin"
} else {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("unable to read file %q: %w", path, err)
}
r = bytes.NewReader(data)
name = path
}
reader, err := f.DecoderFn(name)
if err != nil {
return nil, err
}
return reader(r)
}
type CreateParams struct {
internal.OrgBucketParams
Name string
Stdin io.Reader
ColumnsFile string
ColumnsFormat ColumnsFormat
ExtendedOutput bool
}
func (c Client) Create(ctx context.Context, params CreateParams) error {
cols, err := c.readColumns(params.Stdin, params.ColumnsFormat, params.ColumnsFile)
if err != nil {
return err
}
ids, err := c.resolveOrgBucketIds(ctx, params.OrgBucketParams)
if err != nil {
return err
}
res, _, err := c.BucketSchemasApi.
CreateMeasurementSchema(ctx, ids.BucketID).
OrgID(ids.OrgID).
MeasurementSchemaCreateRequest(api.MeasurementSchemaCreateRequest{
Name: params.Name,
Columns: cols,
}).
Execute()
if err != nil {
return fmt.Errorf("failed to create measurement: %w", err)
}
return c.printMeasurements(ids.BucketID, []api.MeasurementSchema{res}, params.ExtendedOutput)
}
type UpdateParams struct {
internal.OrgBucketParams
Name string
ID string
Stdin io.Reader
ColumnsFile string
ColumnsFormat ColumnsFormat
ExtendedOutput bool
}
func (c Client) Update(ctx context.Context, params UpdateParams) error {
cols, err := c.readColumns(params.Stdin, params.ColumnsFormat, params.ColumnsFile)
if err != nil {
return err
}
ids, err := c.resolveOrgBucketIds(ctx, params.OrgBucketParams)
if err != nil {
return err
}
var id string
if params.ID == "" && params.Name == "" {
return errors.New("measurement id or name required")
} else if params.ID != "" {
id = params.ID
} else {
id, err = c.resolveMeasurement(ctx, *ids, params.Name)
if err != nil {
return err
}
}
res, _, err := c.BucketSchemasApi.
UpdateMeasurementSchema(ctx, ids.BucketID, id).
OrgID(ids.OrgID).
MeasurementSchemaUpdateRequest(api.MeasurementSchemaUpdateRequest{
Columns: cols,
}).
Execute()
if err != nil {
return fmt.Errorf("failed to update measurement schema: %w", err)
}
return c.printMeasurements(ids.BucketID, []api.MeasurementSchema{res}, params.ExtendedOutput)
}
type ListParams struct {
internal.OrgBucketParams
Name string
ExtendedOutput bool
}
func (c Client) List(ctx context.Context, params ListParams) error {
ids, err := c.resolveOrgBucketIds(ctx, params.OrgBucketParams)
if err != nil {
return err
}
req := c.BucketSchemasApi.
GetMeasurementSchemas(ctx, ids.BucketID).
OrgID(ids.OrgID)
if params.Name != "" {
req = req.Name(params.Name)
}
res, _, err := req.Execute()
if err != nil {
return fmt.Errorf("failed to list measurement schemas: %w", err)
}
return c.printMeasurements(ids.BucketID, res.MeasurementSchemas, params.ExtendedOutput)
}
// Constants for table column headers
const (
IDHdr = "ID"
MeasurementNameHdr = "Measurement Name"
ColumnNameHdr = "Column Name"
ColumnTypeHdr = "Column Type"
ColumnDataTypeHdr = "Column Data Type"
BucketIDHdr = "Bucket ID"
)
func (c Client) printMeasurements(bucketID string, m []api.MeasurementSchema, extended bool) error {
if len(m) == 0 {
return nil
}
if c.CLI.PrintAsJSON {
return c.CLI.PrintJSON(m)
}
var headers []string
if extended {
headers = []string{
IDHdr,
MeasurementNameHdr,
ColumnNameHdr,
ColumnTypeHdr,
ColumnDataTypeHdr,
BucketIDHdr,
}
} else {
headers = []string{
IDHdr,
MeasurementNameHdr,
BucketIDHdr,
}
}
var makeRow measurementRowFn
if extended {
makeRow = makeExtendedMeasurementRows
} else {
makeRow = makeMeasurementRows
}
var rows []map[string]interface{}
for i := range m {
rows = append(rows, makeRow(bucketID, &m[i])...)
}
return c.CLI.PrintTable(headers, rows...)
}
type measurementRowFn func(bucketID string, m *api.MeasurementSchema) []map[string]interface{}
func makeMeasurementRows(bucketID string, m *api.MeasurementSchema) []map[string]interface{} {
return []map[string]interface{}{
{
IDHdr: m.Id,
MeasurementNameHdr: m.Name,
BucketIDHdr: bucketID,
},
}
}
func makeExtendedMeasurementRows(bucketID string, m *api.MeasurementSchema) []map[string]interface{} {
rows := make([]map[string]interface{}, 0, len(m.Columns))
for i := range m.Columns {
col := &m.Columns[i]
rows = append(rows, map[string]interface{}{
IDHdr: m.Id,
MeasurementNameHdr: m.Name,
ColumnNameHdr: col.Name,
ColumnTypeHdr: col.Type,
ColumnDataTypeHdr: col.GetDataType(),
BucketIDHdr: bucketID,
})
}
return rows
}

View File

@ -0,0 +1,739 @@
package bucket_schema_test
import (
"bytes"
"context"
"os"
"path/filepath"
"regexp"
"strings"
"testing"
"time"
"github.com/golang/mock/gomock"
"github.com/google/go-cmp/cmp"
"github.com/influxdata/influx-cli/v2/internal"
"github.com/influxdata/influx-cli/v2/internal/api"
"github.com/influxdata/influx-cli/v2/internal/cmd/bucket_schema"
"github.com/influxdata/influx-cli/v2/internal/mock"
"github.com/stretchr/testify/assert"
tmock "github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)
func matchLines(t *testing.T, lines []string, mockIO *mock.Stdio) {
if len(lines) > 0 {
outLines := strings.Split(mockIO.Stdout(), "\n")
expLines := make([]*regexp.Regexp, 0, len(lines))
for _, expLine := range lines {
expLines = append(expLines, regexp.MustCompile(expLine))
}
for _, outLine := range outLines {
if outLine == "" {
continue
}
var any bool
for _, expLine := range expLines {
any = any || expLine.MatchString(outLine)
}
assert.True(t, any, "line %q was unexpected", outLine)
}
}
}
func TestClient_Create(t *testing.T) {
var (
orgID = "dead"
bucketID = "f00d"
measurementID = "1010"
createdAt = time.Date(2004, 4, 9, 2, 15, 0, 0, time.UTC)
)
type setupArgs struct {
buckets *mock.MockBucketsApi
schemas *mock.MockBucketSchemasApi
cli *internal.CLI
params bucket_schema.CreateParams
cols []api.MeasurementSchemaColumn
stdio *mock.Stdio
}
type optFn func(t *testing.T, a *setupArgs)
type args struct {
OrgName string
BucketName string
Name string
ColumnsFile string
ExtendedOutput bool
}
withArgs := func(args args) optFn {
return func(t *testing.T, a *setupArgs) {
t.Helper()
var colFile string
if args.ColumnsFile != "" {
colFile = filepath.Join("testdata", args.ColumnsFile)
}
a.params = bucket_schema.CreateParams{
OrgBucketParams: internal.OrgBucketParams{
OrgParams: internal.OrgParams{OrgName: args.OrgName},
BucketParams: internal.BucketParams{BucketName: args.BucketName},
},
Name: args.Name,
ColumnsFile: colFile,
ExtendedOutput: args.ExtendedOutput,
}
}
}
expGetBuckets := func(n ...string) optFn {
return func(t *testing.T, a *setupArgs) {
t.Helper()
require.True(t, len(n) <= 1, "either zero or one bucket name")
var buckets []api.Bucket
if len(n) == 1 {
bucket := api.NewBucket(n[0], nil)
bucket.SetOrgID(orgID)
bucket.SetId(bucketID)
bucket.SetName(n[0])
buckets = []api.Bucket{*bucket}
}
req := api.ApiGetBucketsRequest{ApiService: a.buckets}
a.buckets.EXPECT().
GetBuckets(gomock.Any()).
Return(req)
a.buckets.EXPECT().
GetBucketsExecute(tmock.MatchedBy(func(in api.ApiGetBucketsRequest) bool {
return cmp.Equal(in.GetOrg(), &a.params.OrgName) && cmp.Equal(in.GetName(), &a.params.BucketName)
})).
Return(api.Buckets{Buckets: &buckets}, nil, nil)
}
}
withCols := func(p string) optFn {
return func(t *testing.T, a *setupArgs) {
data, err := os.ReadFile(filepath.Join("testdata", p))
require.NoError(t, err)
var f bucket_schema.ColumnsFormat
decoder, err := f.DecoderFn(p)
require.NoError(t, err)
cols, err := decoder(bytes.NewReader(data))
require.NoError(t, err)
a.cols = cols
}
}
expCreate := func() optFn {
return func(t *testing.T, a *setupArgs) {
t.Helper()
req := api.ApiCreateMeasurementSchemaRequest{ApiService: a.schemas}.BucketID(bucketID)
a.schemas.EXPECT().
CreateMeasurementSchema(gomock.Any(), bucketID).
Return(req)
a.schemas.EXPECT().
CreateMeasurementSchemaExecute(tmock.MatchedBy(func(in api.ApiCreateMeasurementSchemaRequest) bool {
return cmp.Equal(in.GetOrgID(), &orgID) && cmp.Equal(in.GetBucketID(), bucketID)
})).
Return(api.MeasurementSchema{
Id: measurementID,
Name: a.params.Name,
Columns: a.cols,
CreatedAt: createdAt,
UpdatedAt: createdAt,
}, nil, nil)
}
}
opts := func(opts ...optFn) []optFn { return opts }
lines := func(lines ...string) []string { return lines }
cases := []struct {
name string
opts []optFn
expErr string
expLines []string
}{
{
name: "unable to guess from stdin",
expErr: `unable to guess format for file "stdin"`,
},
{
name: "org arg missing",
opts: opts(
withArgs(args{BucketName: "my-bucket", ColumnsFile: "columns.csv"}),
),
expErr: "org missing: specify org ID or org name",
},
{
name: "bucket arg missing",
opts: opts(
withArgs(args{OrgName: "my-org", ColumnsFile: "columns.csv"}),
),
expErr: "bucket missing: specify bucket ID or bucket name",
},
{
name: "bucket not found",
opts: opts(
withArgs(args{OrgName: "my-org", BucketName: "my-bucket", ColumnsFile: "columns.csv"}),
expGetBuckets(),
),
expErr: `bucket "my-bucket" not found`,
},
{
name: "create succeeds with csv",
opts: opts(
withArgs(args{OrgName: "my-org", BucketName: "my-bucket", Name: "cpu", ColumnsFile: "columns.csv"}),
withCols("columns.csv"),
expGetBuckets("my-bucket"),
expCreate(),
),
expLines: lines(
`^ID\s+Measurement Name\s+Bucket ID$`,
`^1010\s+cpu\s+f00d$`,
),
},
{
name: "create succeeds with json",
opts: opts(
withArgs(args{OrgName: "my-org", BucketName: "my-bucket", Name: "cpu", ColumnsFile: "columns.json"}),
withCols("columns.csv"),
expGetBuckets("my-bucket"),
expCreate(),
),
expLines: lines(
`^ID\s+Measurement Name\s+Bucket ID$`,
`^1010\s+cpu\s+f00d$`,
),
},
{
name: "create succeeds with ndjson",
opts: opts(
withArgs(args{OrgName: "my-org", BucketName: "my-bucket", Name: "cpu", ColumnsFile: "columns.ndjson"}),
withCols("columns.csv"),
expGetBuckets("my-bucket"),
expCreate(),
),
expLines: lines(
`^ID\s+Measurement Name\s+Bucket ID$`,
`^1010\s+cpu\s+f00d$`,
),
},
{
name: "create succeeds with extended output",
opts: opts(
withArgs(args{OrgName: "my-org", BucketName: "my-bucket", Name: "cpu", ColumnsFile: "columns.csv", ExtendedOutput: true}),
withCols("columns.csv"),
expGetBuckets("my-bucket"),
expCreate(),
),
expLines: lines(
`^ID\s+Measurement Name\s+Column Name\s+Column Type\s+Column Data Type\s+Bucket ID$`,
`^1010\s+cpu\s+\w+\s+(timestamp|tag|field)\s+(|float)\s+f00d$`,
),
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
mockIO := mock.NewMockStdio(nil, true)
args := &setupArgs{
buckets: mock.NewMockBucketsApi(ctrl),
schemas: mock.NewMockBucketSchemasApi(ctrl),
stdio: mockIO,
cli: &internal.CLI{StdIO: mockIO},
}
for _, opt := range tc.opts {
opt(t, args)
}
c := bucket_schema.Client{
BucketApi: args.buckets,
BucketSchemasApi: args.schemas,
CLI: args.cli,
}
ctx := context.Background()
err := c.Create(ctx, args.params)
if tc.expErr != "" {
assert.EqualError(t, err, tc.expErr)
} else {
require.NoError(t, err)
matchLines(t, tc.expLines, mockIO)
}
})
}
}
func TestClient_Update(t *testing.T) {
var (
orgID = "dead"
bucketID = "f00d"
measurementID = "1010"
createdAt = time.Date(2004, 4, 9, 2, 15, 0, 0, time.UTC)
updatedAt = time.Date(2009, 9, 1, 2, 15, 0, 0, time.UTC)
)
type setupArgs struct {
buckets *mock.MockBucketsApi
schemas *mock.MockBucketSchemasApi
cli *internal.CLI
params bucket_schema.UpdateParams
cols []api.MeasurementSchemaColumn
stdio *mock.Stdio
}
type optFn func(t *testing.T, a *setupArgs)
type args struct {
OrgName string
BucketName string
Name string
ColumnsFile string
ExtendedOutput bool
}
withArgs := func(args args) optFn {
return func(t *testing.T, a *setupArgs) {
t.Helper()
var colFile string
if args.ColumnsFile != "" {
colFile = filepath.Join("testdata", args.ColumnsFile)
}
a.params = bucket_schema.UpdateParams{
OrgBucketParams: internal.OrgBucketParams{
OrgParams: internal.OrgParams{OrgName: args.OrgName},
BucketParams: internal.BucketParams{BucketName: args.BucketName},
},
Name: args.Name,
ColumnsFile: colFile,
ExtendedOutput: args.ExtendedOutput,
}
}
}
expGetBuckets := func(n ...string) optFn {
return func(t *testing.T, a *setupArgs) {
t.Helper()
require.True(t, len(n) <= 1, "either zero or one bucket name")
var buckets []api.Bucket
if len(n) == 1 {
bucket := api.NewBucket(n[0], nil)
bucket.SetOrgID(orgID)
bucket.SetId(bucketID)
bucket.SetName(n[0])
buckets = []api.Bucket{*bucket}
}
req := api.ApiGetBucketsRequest{ApiService: a.buckets}
a.buckets.EXPECT().
GetBuckets(gomock.Any()).
Return(req)
a.buckets.EXPECT().
GetBucketsExecute(tmock.MatchedBy(func(in api.ApiGetBucketsRequest) bool {
return (in.GetOrg() != nil && *in.GetOrg() == a.params.OrgName) &&
(in.GetName() != nil && *in.GetName() == a.params.BucketName)
})).
Return(api.Buckets{Buckets: &buckets}, nil, nil)
}
}
withCols := func(p string) optFn {
return func(t *testing.T, a *setupArgs) {
data, err := os.ReadFile(filepath.Join("testdata", p))
require.NoError(t, err)
var f bucket_schema.ColumnsFormat
decoder, err := f.DecoderFn(p)
require.NoError(t, err)
cols, err := decoder(bytes.NewReader(data))
require.NoError(t, err)
a.cols = cols
}
}
expGetMeasurementSchema := func() optFn {
return func(t *testing.T, a *setupArgs) {
t.Helper()
req := api.ApiGetMeasurementSchemasRequest{ApiService: a.schemas}.BucketID(bucketID)
a.schemas.EXPECT().
GetMeasurementSchemas(gomock.Any(), bucketID).
Return(req)
a.schemas.EXPECT().
GetMeasurementSchemasExecute(tmock.MatchedBy(func(in api.ApiGetMeasurementSchemasRequest) bool {
return (in.GetOrgID() != nil && *in.GetOrgID() == orgID) &&
in.GetBucketID() == bucketID &&
(in.GetName() != nil && *in.GetName() == a.params.Name)
})).
Return(api.MeasurementSchemaList{
MeasurementSchemas: []api.MeasurementSchema{
{
Id: measurementID,
Name: a.params.Name,
Columns: a.cols,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
},
},
}, nil, nil)
}
}
expUpdate := func() optFn {
return func(t *testing.T, a *setupArgs) {
t.Helper()
req := api.ApiUpdateMeasurementSchemaRequest{ApiService: a.schemas}.BucketID(bucketID).MeasurementID(measurementID)
a.schemas.EXPECT().
UpdateMeasurementSchema(gomock.Any(), bucketID, measurementID).
Return(req)
a.schemas.EXPECT().
UpdateMeasurementSchemaExecute(tmock.MatchedBy(func(in api.ApiUpdateMeasurementSchemaRequest) bool {
return cmp.Equal(in.GetOrgID(), &orgID) &&
cmp.Equal(in.GetBucketID(), bucketID) &&
cmp.Equal(in.GetMeasurementID(), measurementID) &&
cmp.Equal(in.GetMeasurementSchemaUpdateRequest().Columns, a.cols)
})).
Return(api.MeasurementSchema{
Id: measurementID,
Name: a.params.Name,
Columns: a.cols,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
}, nil, nil)
}
}
opts := func(opts ...optFn) []optFn { return opts }
lines := func(lines ...string) []string { return lines }
cases := []struct {
name string
opts []optFn
expErr string
expLines []string
}{
{
name: "unable to guess from stdin",
expErr: `unable to guess format for file "stdin"`,
},
{
name: "org arg missing",
opts: opts(
withArgs(args{BucketName: "my-bucket", ColumnsFile: "columns.csv"}),
),
expErr: "org missing: specify org ID or org name",
},
{
name: "bucket arg missing",
opts: opts(
withArgs(args{OrgName: "my-org", ColumnsFile: "columns.csv"}),
),
expErr: "bucket missing: specify bucket ID or bucket name",
},
{
name: "bucket not found",
opts: opts(
withArgs(args{OrgName: "my-org", BucketName: "my-bucket", ColumnsFile: "columns.csv"}),
expGetBuckets(),
),
expErr: `bucket "my-bucket" not found`,
},
{
name: "update succeeds",
opts: opts(
withArgs(args{OrgName: "my-org", BucketName: "my-bucket", Name: "cpu", ColumnsFile: "columns.csv"}),
withCols("columns.csv"),
expGetBuckets("my-bucket"),
expGetMeasurementSchema(),
expUpdate(),
),
expLines: lines(
`^ID\s+Measurement Name\s+Bucket ID$`,
`^1010\s+cpu\s+f00d$`,
),
},
{
name: "update succeeds extended output",
opts: opts(
withArgs(args{OrgName: "my-org", BucketName: "my-bucket", Name: "cpu", ColumnsFile: "columns.csv", ExtendedOutput: true}),
withCols("columns.csv"),
expGetBuckets("my-bucket"),
expGetMeasurementSchema(),
expUpdate(),
),
expLines: lines(
`^ID\s+Measurement Name\s+Column Name\s+Column Type\s+Column Data Type\s+Bucket ID$`,
`^1010\s+cpu\s+\w+\s+(timestamp|tag|field)\s+(|float)\s+f00d$`,
),
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
mockIO := mock.NewMockStdio(nil, true)
args := &setupArgs{
buckets: mock.NewMockBucketsApi(ctrl),
schemas: mock.NewMockBucketSchemasApi(ctrl),
stdio: mockIO,
cli: &internal.CLI{StdIO: mockIO},
}
for _, opt := range tc.opts {
opt(t, args)
}
c := bucket_schema.Client{
BucketApi: args.buckets,
BucketSchemasApi: args.schemas,
CLI: args.cli,
}
ctx := context.Background()
err := c.Update(ctx, args.params)
if tc.expErr != "" {
assert.EqualError(t, err, tc.expErr)
} else {
require.NoError(t, err)
matchLines(t, tc.expLines, mockIO)
}
})
}
}
func TestClient_List(t *testing.T) {
var (
orgID = "dead"
bucketID = "f00d"
measurementID = "1010"
createdAt = time.Date(2004, 4, 9, 2, 15, 0, 0, time.UTC)
updatedAt = time.Date(2009, 9, 1, 2, 15, 0, 0, time.UTC)
)
type setupArgs struct {
buckets *mock.MockBucketsApi
schemas *mock.MockBucketSchemasApi
cli *internal.CLI
params bucket_schema.ListParams
cols []api.MeasurementSchemaColumn
stdio *mock.Stdio
}
type optFn func(t *testing.T, a *setupArgs)
type args struct {
OrgName string
BucketName string
Name string
ExtendedOutput bool
}
withArgs := func(args args) optFn {
return func(t *testing.T, a *setupArgs) {
t.Helper()
a.params = bucket_schema.ListParams{
OrgBucketParams: internal.OrgBucketParams{
OrgParams: internal.OrgParams{OrgName: args.OrgName},
BucketParams: internal.BucketParams{BucketName: args.BucketName},
},
Name: args.Name,
ExtendedOutput: args.ExtendedOutput,
}
}
}
expGetBuckets := func(n ...string) optFn {
return func(t *testing.T, a *setupArgs) {
t.Helper()
require.True(t, len(n) <= 1, "either zero or one bucket name")
var buckets []api.Bucket
if len(n) == 1 {
bucket := api.NewBucket(n[0], nil)
bucket.SetOrgID(orgID)
bucket.SetId(bucketID)
bucket.SetName(n[0])
buckets = []api.Bucket{*bucket}
}
req := api.ApiGetBucketsRequest{ApiService: a.buckets}
a.buckets.EXPECT().
GetBuckets(gomock.Any()).
Return(req)
a.buckets.EXPECT().
GetBucketsExecute(tmock.MatchedBy(func(in api.ApiGetBucketsRequest) bool {
return (in.GetOrg() != nil && *in.GetOrg() == a.params.OrgName) &&
(in.GetName() != nil && *in.GetName() == a.params.BucketName)
})).
Return(api.Buckets{Buckets: &buckets}, nil, nil)
}
}
withCols := func(p string) optFn {
return func(t *testing.T, a *setupArgs) {
data, err := os.ReadFile(filepath.Join("testdata", p))
require.NoError(t, err)
var f bucket_schema.ColumnsFormat
decoder, err := f.DecoderFn(p)
require.NoError(t, err)
cols, err := decoder(bytes.NewReader(data))
require.NoError(t, err)
a.cols = cols
}
}
expGetMeasurementSchemas := func() optFn {
return func(t *testing.T, a *setupArgs) {
t.Helper()
req := api.ApiGetMeasurementSchemasRequest{ApiService: a.schemas}.BucketID(bucketID)
a.schemas.EXPECT().
GetMeasurementSchemas(gomock.Any(), bucketID).
Return(req)
a.schemas.EXPECT().
GetMeasurementSchemasExecute(tmock.MatchedBy(func(in api.ApiGetMeasurementSchemasRequest) bool {
return (in.GetOrgID() != nil && *in.GetOrgID() == orgID) &&
in.GetBucketID() == bucketID &&
(in.GetName() != nil && *in.GetName() == a.params.Name)
})).
Return(api.MeasurementSchemaList{
MeasurementSchemas: []api.MeasurementSchema{
{
Id: measurementID,
Name: a.params.Name,
Columns: a.cols,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
},
},
}, nil, nil)
}
}
opts := func(opts ...optFn) []optFn { return opts }
lines := func(lines ...string) []string { return lines }
cases := []struct {
name string
opts []optFn
expErr string
expLines []string
}{
{
name: "org arg missing",
opts: opts(
withArgs(args{BucketName: "my-bucket"}),
),
expErr: "org missing: specify org ID or org name",
},
{
name: "bucket arg missing",
opts: opts(
withArgs(args{OrgName: "my-org"}),
),
expErr: "bucket missing: specify bucket ID or bucket name",
},
{
name: "bucket not found",
opts: opts(
withArgs(args{OrgName: "my-org", BucketName: "my-bucket"}),
expGetBuckets(),
),
expErr: `bucket "my-bucket" not found`,
},
{
name: "update succeeds",
opts: opts(
withArgs(args{OrgName: "my-org", BucketName: "my-bucket", Name: "cpu"}),
withCols("columns.csv"),
expGetBuckets("my-bucket"),
expGetMeasurementSchemas(),
),
expLines: lines(
`^ID\s+Measurement Name\s+Bucket ID$`,
`^1010\s+cpu\s+f00d$`,
),
},
{
name: "update succeeds extended output",
opts: opts(
withArgs(args{OrgName: "my-org", BucketName: "my-bucket", Name: "cpu", ExtendedOutput: true}),
withCols("columns.csv"),
expGetBuckets("my-bucket"),
expGetMeasurementSchemas(),
),
expLines: lines(
`^ID\s+Measurement Name\s+Column Name\s+Column Type\s+Column Data Type\s+Bucket ID$`,
`^1010\s+cpu\s+\w+\s+(timestamp|tag|field)\s+(|float)\s+f00d$`,
),
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
mockIO := mock.NewMockStdio(nil, true)
args := &setupArgs{
buckets: mock.NewMockBucketsApi(ctrl),
schemas: mock.NewMockBucketSchemasApi(ctrl),
stdio: mockIO,
cli: &internal.CLI{StdIO: mockIO},
}
for _, opt := range tc.opts {
opt(t, args)
}
c := bucket_schema.Client{
BucketApi: args.buckets,
BucketSchemasApi: args.schemas,
CLI: args.cli,
}
ctx := context.Background()
err := c.List(ctx, args.params)
if tc.expErr != "" {
assert.EqualError(t, err, tc.expErr)
} else {
require.NoError(t, err)
matchLines(t, tc.expLines, mockIO)
}
})
}
}

View File

@ -0,0 +1,35 @@
package bucket_schema
import (
"fmt"
"io"
"github.com/gocarina/gocsv"
"github.com/influxdata/influx-cli/v2/internal/api"
)
type csvColumn struct {
Name string `csv:"name"`
Type api.ColumnSemanticType `csv:"type"`
DataType *api.ColumnDataType `csv:"data_type,omitempty"`
}
func decodeCSV(r io.Reader) ([]api.MeasurementSchemaColumn, error) {
var cols []csvColumn
gocsv.FailIfUnmatchedStructTags = true
err := gocsv.Unmarshal(r, &cols)
if err != nil {
return nil, fmt.Errorf("failed to decode CSV: %w", err)
}
rows := make([]api.MeasurementSchemaColumn, 0, len(cols))
for i := range cols {
c := &cols[i]
rows = append(rows, api.MeasurementSchemaColumn{
Name: c.Name,
Type: c.Type,
DataType: c.DataType,
})
}
return rows, nil
}

View File

@ -0,0 +1,85 @@
package bucket_schema
import (
"strings"
"testing"
"github.com/MakeNowJust/heredoc/v2"
"github.com/influxdata/influx-cli/v2/internal/api"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestDecodeCSV(t *testing.T) {
tests := []struct {
name string
data string
exp []api.MeasurementSchemaColumn
expErr string
}{
{
name: "valid",
data: heredoc.Doc(`
name,type,data_type
time,timestamp,
host,tag,
usage_user,field,float
`),
exp: cols(colTs(), colT("host"), colFF("usage_user")),
},
{
name: "valid with alternate order",
data: heredoc.Doc(`
type,data_type,name
timestamp,,time
tag,,host
field,float,usage_user
`),
exp: cols(colTs(), colT("host"), colFF("usage_user")),
},
{
name: "invalid column type",
data: heredoc.Doc(`
name,type,data_type
time,foo,
`),
expErr: `failed to decode CSV: record on line 0; parse error on line 2, column 2: "foo" is not a valid column type. Valid values are [timestamp, tag, field]`,
},
{
name: "invalid column data type",
data: heredoc.Doc(`
name,type,data_type
time,field,floaty
`),
expErr: `failed to decode CSV: record on line 0; parse error on line 2, column 3: "floaty" is not a valid column data type. Valid values are [integer, float, boolean, string, unsigned]`,
},
{
name: "invalid headers",
data: heredoc.Doc(`
name,foo
time,field
`),
expErr: `failed to decode CSV: found unmatched struct field with tags [type data_type]`,
},
{
name: "invalid CSV",
data: heredoc.Doc(`
type,type,data_type
time,timestamp
`),
expErr: `failed to decode CSV: record on line 2: wrong number of fields`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := strings.NewReader(tt.data)
got, err := decodeCSV(r)
if tt.expErr != "" {
assert.EqualError(t, err, tt.expErr)
} else {
require.NoError(t, err)
assert.Equal(t, tt.exp, got)
}
})
}
}

View File

@ -0,0 +1,86 @@
package bucket_schema
import (
"fmt"
"io"
"path/filepath"
"strconv"
"strings"
"github.com/influxdata/influx-cli/v2/internal/api"
)
// ColumnsFormat is a type which defines the supported formats
//
type ColumnsFormat int
const (
ColumnsFormatAuto ColumnsFormat = iota
ColumnsFormatCSV
ColumnsFormatNDJson
ColumnsFormatJson
)
func (f *ColumnsFormat) Set(v string) error {
switch v {
case "auto":
*f = ColumnsFormatAuto
case "csv":
*f = ColumnsFormatCSV
case "ndjson":
*f = ColumnsFormatNDJson
case "json":
*f = ColumnsFormatJson
default:
return fmt.Errorf("invalid columns-format: %s, expected [csv, ndjson, json, auto]", v)
}
return nil
}
func (f ColumnsFormat) String() string {
switch f {
case ColumnsFormatAuto:
return "auto"
case ColumnsFormatCSV:
return "csv"
case ColumnsFormatNDJson:
return "ndjson"
case ColumnsFormatJson:
return "json"
default:
return "schema.Format(" + strconv.FormatInt(int64(f), 10) + ")"
}
}
// DecoderFn uses f and path to return a function capable of decoding
// measurement schema columns from a given io.Reader. If no combination
// of decoder exists for f and path, DecoderFn returns an error.
func (f ColumnsFormat) DecoderFn(path string) (ColumnsDecoderFn, error) {
ff := f
if ff == ColumnsFormatAuto {
ext := filepath.Ext(path)
switch {
case strings.EqualFold(ext, ".csv"):
ff = ColumnsFormatCSV
case strings.EqualFold(ext, ".json"):
ff = ColumnsFormatJson
case strings.EqualFold(ext, ".ndjson") || strings.EqualFold(ext, ".jsonl"):
ff = ColumnsFormatNDJson
}
}
switch ff {
case ColumnsFormatCSV:
return decodeCSV, nil
case ColumnsFormatNDJson:
return decodeNDJson, nil
case ColumnsFormatJson:
return decodeJson, nil
}
return nil, fmt.Errorf("unable to guess format for file %q", path)
}
// ColumnsDecoderFn is a function which decodes a slice of api.MeasurementSchemaColumn
// elements from r.
type ColumnsDecoderFn func(r io.Reader) ([]api.MeasurementSchemaColumn, error)

View File

@ -0,0 +1,17 @@
package bucket_schema
import (
"encoding/json"
"fmt"
"io"
"github.com/influxdata/influx-cli/v2/internal/api"
)
func decodeJson(r io.Reader) ([]api.MeasurementSchemaColumn, error) {
var rows []api.MeasurementSchemaColumn
if err := json.NewDecoder(r).Decode(&rows); err != nil {
return nil, fmt.Errorf("error decoding JSON: %w", err)
}
return rows, nil
}

View File

@ -0,0 +1,70 @@
package bucket_schema
import (
"strings"
"testing"
"github.com/MakeNowJust/heredoc/v2"
"github.com/influxdata/influx-cli/v2/internal/api"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestDecodeJson(t *testing.T) {
tests := []struct {
name string
data string
exp []api.MeasurementSchemaColumn
expErr string
}{
{
name: "valid",
data: heredoc.Doc(`
[
{ "name": "time", "type": "timestamp" },
{ "name": "host", "type": "tag" },
{ "name": "usage_user", "type": "field", "dataType": "float" }
]
`),
exp: cols(colTs(), colT("host"), colFF("usage_user")),
},
{
name: "invalid column type",
data: heredoc.Doc(`
[
{ "name": "time", "type": "foo" }
]
`),
expErr: `error decoding JSON: foo is not a valid ColumnSemanticType`,
},
{
name: "invalid column data type",
data: heredoc.Doc(`
[
{ "name": "time", "type": "field", "dataType": "floaty" }
]
`),
expErr: `error decoding JSON: floaty is not a valid ColumnDataType`,
},
{
name: "invalid JSON",
data: heredoc.Doc(`
[
{ "name": "time", "type": "field", "dataType": "floaty" }
`),
expErr: `error decoding JSON: unexpected EOF`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := strings.NewReader(tt.data)
got, err := decodeJson(r)
if tt.expErr != "" {
assert.EqualError(t, err, tt.expErr)
} else {
require.NoError(t, err)
assert.Equal(t, tt.exp, got)
}
})
}
}

View File

@ -0,0 +1,28 @@
package bucket_schema
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"io"
"github.com/influxdata/influx-cli/v2/internal/api"
)
func decodeNDJson(r io.Reader) ([]api.MeasurementSchemaColumn, error) {
scan := bufio.NewScanner(r)
var rows []api.MeasurementSchemaColumn
n := 1
for scan.Scan() {
if line := bytes.TrimSpace(scan.Bytes()); len(line) > 0 {
var row api.MeasurementSchemaColumn
if err := json.Unmarshal(line, &row); err != nil {
return nil, fmt.Errorf("error decoding JSON at line %d: %w", n, err)
}
rows = append(rows, row)
}
n++
}
return rows, nil
}

View File

@ -0,0 +1,78 @@
package bucket_schema
import (
"strings"
"testing"
"github.com/MakeNowJust/heredoc/v2"
"github.com/influxdata/influx-cli/v2/internal/api"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func colTs() api.MeasurementSchemaColumn {
return api.MeasurementSchemaColumn{Name: "time", Type: api.COLUMNSEMANTICTYPE_TIMESTAMP}
}
func colT(n string) api.MeasurementSchemaColumn {
return api.MeasurementSchemaColumn{Name: n, Type: api.COLUMNSEMANTICTYPE_TAG}
}
func colFF(n string) api.MeasurementSchemaColumn {
return api.MeasurementSchemaColumn{Name: n, Type: api.COLUMNSEMANTICTYPE_FIELD, DataType: api.COLUMNDATATYPE_FLOAT.Ptr()}
}
func cols(c ...api.MeasurementSchemaColumn) []api.MeasurementSchemaColumn { return c }
func TestDecodeNDJson(t *testing.T) {
tests := []struct {
name string
data string
exp []api.MeasurementSchemaColumn
expErr string
}{
{
name: "valid",
data: heredoc.Doc(`
{ "name": "time", "type": "timestamp" }
{ "name": "host", "type": "tag" }
{ "name": "usage_user", "type": "field", "dataType": "float" }
`),
exp: cols(colTs(), colT("host"), colFF("usage_user")),
},
{
name: "invalid column type",
data: heredoc.Doc(`
{ "name": "time", "type": "foo" }
`),
expErr: `error decoding JSON at line 1: foo is not a valid ColumnSemanticType`,
},
{
name: "invalid column data type",
data: heredoc.Doc(`
{ "name": "time", "type": "field", "dataType": "floaty" }
`),
expErr: `error decoding JSON at line 1: floaty is not a valid ColumnDataType`,
},
{
name: "invalid JSON",
data: heredoc.Doc(`
{ "name": "usage_user", "type": "field", "dataType": "float" }
{ "name": "time", "type": "field", "dataType": "float"
`),
expErr: `error decoding JSON at line 2: unexpected end of JSON input`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := strings.NewReader(tt.data)
got, err := decodeNDJson(r)
if tt.expErr != "" {
assert.EqualError(t, err, tt.expErr)
} else {
require.NoError(t, err)
assert.Equal(t, tt.exp, got)
}
})
}
}

View File

@ -0,0 +1,4 @@
name,type,data_type
time,timestamp,
host,tag,
usage_user,field,float
1 name type data_type
2 time timestamp
3 host tag
4 usage_user field float

View File

@ -0,0 +1,5 @@
[
{ "name": "time", "type": "timestamp" },
{ "name": "host", "type": "tag" },
{ "name": "usage_user", "type": "field", "dataType": "float" }
]

View File

@ -0,0 +1,3 @@
{ "name": "time", "type": "timestamp" }
{ "name": "host", "type": "tag" }
{ "name": "usage_user", "type": "field", "dataType": "float" }

View File

@ -0,0 +1,157 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/influxdata/influx-cli/v2/internal/api (interfaces: BucketSchemasApi)
// Package mock is a generated GoMock package.
package mock
import (
context "context"
http "net/http"
reflect "reflect"
gomock "github.com/golang/mock/gomock"
api "github.com/influxdata/influx-cli/v2/internal/api"
)
// MockBucketSchemasApi is a mock of BucketSchemasApi interface.
type MockBucketSchemasApi struct {
ctrl *gomock.Controller
recorder *MockBucketSchemasApiMockRecorder
}
// MockBucketSchemasApiMockRecorder is the mock recorder for MockBucketSchemasApi.
type MockBucketSchemasApiMockRecorder struct {
mock *MockBucketSchemasApi
}
// NewMockBucketSchemasApi creates a new mock instance.
func NewMockBucketSchemasApi(ctrl *gomock.Controller) *MockBucketSchemasApi {
mock := &MockBucketSchemasApi{ctrl: ctrl}
mock.recorder = &MockBucketSchemasApiMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockBucketSchemasApi) EXPECT() *MockBucketSchemasApiMockRecorder {
return m.recorder
}
// CreateMeasurementSchema mocks base method.
func (m *MockBucketSchemasApi) CreateMeasurementSchema(arg0 context.Context, arg1 string) api.ApiCreateMeasurementSchemaRequest {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateMeasurementSchema", arg0, arg1)
ret0, _ := ret[0].(api.ApiCreateMeasurementSchemaRequest)
return ret0
}
// CreateMeasurementSchema indicates an expected call of CreateMeasurementSchema.
func (mr *MockBucketSchemasApiMockRecorder) CreateMeasurementSchema(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateMeasurementSchema", reflect.TypeOf((*MockBucketSchemasApi)(nil).CreateMeasurementSchema), arg0, arg1)
}
// CreateMeasurementSchemaExecute mocks base method.
func (m *MockBucketSchemasApi) CreateMeasurementSchemaExecute(arg0 api.ApiCreateMeasurementSchemaRequest) (api.MeasurementSchema, *http.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateMeasurementSchemaExecute", arg0)
ret0, _ := ret[0].(api.MeasurementSchema)
ret1, _ := ret[1].(*http.Response)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// CreateMeasurementSchemaExecute indicates an expected call of CreateMeasurementSchemaExecute.
func (mr *MockBucketSchemasApiMockRecorder) CreateMeasurementSchemaExecute(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateMeasurementSchemaExecute", reflect.TypeOf((*MockBucketSchemasApi)(nil).CreateMeasurementSchemaExecute), arg0)
}
// GetMeasurementSchema mocks base method.
func (m *MockBucketSchemasApi) GetMeasurementSchema(arg0 context.Context, arg1, arg2 string) api.ApiGetMeasurementSchemaRequest {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetMeasurementSchema", arg0, arg1, arg2)
ret0, _ := ret[0].(api.ApiGetMeasurementSchemaRequest)
return ret0
}
// GetMeasurementSchema indicates an expected call of GetMeasurementSchema.
func (mr *MockBucketSchemasApiMockRecorder) GetMeasurementSchema(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMeasurementSchema", reflect.TypeOf((*MockBucketSchemasApi)(nil).GetMeasurementSchema), arg0, arg1, arg2)
}
// GetMeasurementSchemaExecute mocks base method.
func (m *MockBucketSchemasApi) GetMeasurementSchemaExecute(arg0 api.ApiGetMeasurementSchemaRequest) (api.MeasurementSchema, *http.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetMeasurementSchemaExecute", arg0)
ret0, _ := ret[0].(api.MeasurementSchema)
ret1, _ := ret[1].(*http.Response)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// GetMeasurementSchemaExecute indicates an expected call of GetMeasurementSchemaExecute.
func (mr *MockBucketSchemasApiMockRecorder) GetMeasurementSchemaExecute(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMeasurementSchemaExecute", reflect.TypeOf((*MockBucketSchemasApi)(nil).GetMeasurementSchemaExecute), arg0)
}
// GetMeasurementSchemas mocks base method.
func (m *MockBucketSchemasApi) GetMeasurementSchemas(arg0 context.Context, arg1 string) api.ApiGetMeasurementSchemasRequest {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetMeasurementSchemas", arg0, arg1)
ret0, _ := ret[0].(api.ApiGetMeasurementSchemasRequest)
return ret0
}
// GetMeasurementSchemas indicates an expected call of GetMeasurementSchemas.
func (mr *MockBucketSchemasApiMockRecorder) GetMeasurementSchemas(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMeasurementSchemas", reflect.TypeOf((*MockBucketSchemasApi)(nil).GetMeasurementSchemas), arg0, arg1)
}
// GetMeasurementSchemasExecute mocks base method.
func (m *MockBucketSchemasApi) GetMeasurementSchemasExecute(arg0 api.ApiGetMeasurementSchemasRequest) (api.MeasurementSchemaList, *http.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetMeasurementSchemasExecute", arg0)
ret0, _ := ret[0].(api.MeasurementSchemaList)
ret1, _ := ret[1].(*http.Response)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// GetMeasurementSchemasExecute indicates an expected call of GetMeasurementSchemasExecute.
func (mr *MockBucketSchemasApiMockRecorder) GetMeasurementSchemasExecute(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMeasurementSchemasExecute", reflect.TypeOf((*MockBucketSchemasApi)(nil).GetMeasurementSchemasExecute), arg0)
}
// UpdateMeasurementSchema mocks base method.
func (m *MockBucketSchemasApi) UpdateMeasurementSchema(arg0 context.Context, arg1, arg2 string) api.ApiUpdateMeasurementSchemaRequest {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateMeasurementSchema", arg0, arg1, arg2)
ret0, _ := ret[0].(api.ApiUpdateMeasurementSchemaRequest)
return ret0
}
// UpdateMeasurementSchema indicates an expected call of UpdateMeasurementSchema.
func (mr *MockBucketSchemasApiMockRecorder) UpdateMeasurementSchema(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateMeasurementSchema", reflect.TypeOf((*MockBucketSchemasApi)(nil).UpdateMeasurementSchema), arg0, arg1, arg2)
}
// UpdateMeasurementSchemaExecute mocks base method.
func (m *MockBucketSchemasApi) UpdateMeasurementSchemaExecute(arg0 api.ApiUpdateMeasurementSchemaRequest) (api.MeasurementSchema, *http.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateMeasurementSchemaExecute", arg0)
ret0, _ := ret[0].(api.MeasurementSchema)
ret1, _ := ret[1].(*http.Response)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// UpdateMeasurementSchemaExecute indicates an expected call of UpdateMeasurementSchemaExecute.
func (mr *MockBucketSchemasApiMockRecorder) UpdateMeasurementSchemaExecute(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateMeasurementSchemaExecute", reflect.TypeOf((*MockBucketSchemasApi)(nil).UpdateMeasurementSchemaExecute), arg0)
}

View File

@ -0,0 +1,186 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/influxdata/influx-cli/v2/internal/api (interfaces: BucketsApi)
// Package mock is a generated GoMock package.
package mock
import (
context "context"
http "net/http"
reflect "reflect"
gomock "github.com/golang/mock/gomock"
api "github.com/influxdata/influx-cli/v2/internal/api"
)
// MockBucketsApi is a mock of BucketsApi interface.
type MockBucketsApi struct {
ctrl *gomock.Controller
recorder *MockBucketsApiMockRecorder
}
// MockBucketsApiMockRecorder is the mock recorder for MockBucketsApi.
type MockBucketsApiMockRecorder struct {
mock *MockBucketsApi
}
// NewMockBucketsApi creates a new mock instance.
func NewMockBucketsApi(ctrl *gomock.Controller) *MockBucketsApi {
mock := &MockBucketsApi{ctrl: ctrl}
mock.recorder = &MockBucketsApiMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockBucketsApi) EXPECT() *MockBucketsApiMockRecorder {
return m.recorder
}
// DeleteBucketsID mocks base method.
func (m *MockBucketsApi) DeleteBucketsID(arg0 context.Context, arg1 string) api.ApiDeleteBucketsIDRequest {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteBucketsID", arg0, arg1)
ret0, _ := ret[0].(api.ApiDeleteBucketsIDRequest)
return ret0
}
// DeleteBucketsID indicates an expected call of DeleteBucketsID.
func (mr *MockBucketsApiMockRecorder) DeleteBucketsID(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketsID", reflect.TypeOf((*MockBucketsApi)(nil).DeleteBucketsID), arg0, arg1)
}
// DeleteBucketsIDExecute mocks base method.
func (m *MockBucketsApi) DeleteBucketsIDExecute(arg0 api.ApiDeleteBucketsIDRequest) (*http.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteBucketsIDExecute", arg0)
ret0, _ := ret[0].(*http.Response)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// DeleteBucketsIDExecute indicates an expected call of DeleteBucketsIDExecute.
func (mr *MockBucketsApiMockRecorder) DeleteBucketsIDExecute(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBucketsIDExecute", reflect.TypeOf((*MockBucketsApi)(nil).DeleteBucketsIDExecute), arg0)
}
// GetBuckets mocks base method.
func (m *MockBucketsApi) GetBuckets(arg0 context.Context) api.ApiGetBucketsRequest {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBuckets", arg0)
ret0, _ := ret[0].(api.ApiGetBucketsRequest)
return ret0
}
// GetBuckets indicates an expected call of GetBuckets.
func (mr *MockBucketsApiMockRecorder) GetBuckets(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBuckets", reflect.TypeOf((*MockBucketsApi)(nil).GetBuckets), arg0)
}
// GetBucketsExecute mocks base method.
func (m *MockBucketsApi) GetBucketsExecute(arg0 api.ApiGetBucketsRequest) (api.Buckets, *http.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBucketsExecute", arg0)
ret0, _ := ret[0].(api.Buckets)
ret1, _ := ret[1].(*http.Response)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// GetBucketsExecute indicates an expected call of GetBucketsExecute.
func (mr *MockBucketsApiMockRecorder) GetBucketsExecute(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketsExecute", reflect.TypeOf((*MockBucketsApi)(nil).GetBucketsExecute), arg0)
}
// GetBucketsID mocks base method.
func (m *MockBucketsApi) GetBucketsID(arg0 context.Context, arg1 string) api.ApiGetBucketsIDRequest {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBucketsID", arg0, arg1)
ret0, _ := ret[0].(api.ApiGetBucketsIDRequest)
return ret0
}
// GetBucketsID indicates an expected call of GetBucketsID.
func (mr *MockBucketsApiMockRecorder) GetBucketsID(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketsID", reflect.TypeOf((*MockBucketsApi)(nil).GetBucketsID), arg0, arg1)
}
// GetBucketsIDExecute mocks base method.
func (m *MockBucketsApi) GetBucketsIDExecute(arg0 api.ApiGetBucketsIDRequest) (api.Bucket, *http.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBucketsIDExecute", arg0)
ret0, _ := ret[0].(api.Bucket)
ret1, _ := ret[1].(*http.Response)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// GetBucketsIDExecute indicates an expected call of GetBucketsIDExecute.
func (mr *MockBucketsApiMockRecorder) GetBucketsIDExecute(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBucketsIDExecute", reflect.TypeOf((*MockBucketsApi)(nil).GetBucketsIDExecute), arg0)
}
// PatchBucketsID mocks base method.
func (m *MockBucketsApi) PatchBucketsID(arg0 context.Context, arg1 string) api.ApiPatchBucketsIDRequest {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "PatchBucketsID", arg0, arg1)
ret0, _ := ret[0].(api.ApiPatchBucketsIDRequest)
return ret0
}
// PatchBucketsID indicates an expected call of PatchBucketsID.
func (mr *MockBucketsApiMockRecorder) PatchBucketsID(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PatchBucketsID", reflect.TypeOf((*MockBucketsApi)(nil).PatchBucketsID), arg0, arg1)
}
// PatchBucketsIDExecute mocks base method.
func (m *MockBucketsApi) PatchBucketsIDExecute(arg0 api.ApiPatchBucketsIDRequest) (api.Bucket, *http.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "PatchBucketsIDExecute", arg0)
ret0, _ := ret[0].(api.Bucket)
ret1, _ := ret[1].(*http.Response)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// PatchBucketsIDExecute indicates an expected call of PatchBucketsIDExecute.
func (mr *MockBucketsApiMockRecorder) PatchBucketsIDExecute(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PatchBucketsIDExecute", reflect.TypeOf((*MockBucketsApi)(nil).PatchBucketsIDExecute), arg0)
}
// PostBuckets mocks base method.
func (m *MockBucketsApi) PostBuckets(arg0 context.Context) api.ApiPostBucketsRequest {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "PostBuckets", arg0)
ret0, _ := ret[0].(api.ApiPostBucketsRequest)
return ret0
}
// PostBuckets indicates an expected call of PostBuckets.
func (mr *MockBucketsApiMockRecorder) PostBuckets(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PostBuckets", reflect.TypeOf((*MockBucketsApi)(nil).PostBuckets), arg0)
}
// PostBucketsExecute mocks base method.
func (m *MockBucketsApi) PostBucketsExecute(arg0 api.ApiPostBucketsRequest) (api.Bucket, *http.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "PostBucketsExecute", arg0)
ret0, _ := ret[0].(api.Bucket)
ret1, _ := ret[1].(*http.Response)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// PostBucketsExecute indicates an expected call of PostBucketsExecute.
func (mr *MockBucketsApiMockRecorder) PostBucketsExecute(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PostBucketsExecute", reflect.TypeOf((*MockBucketsApi)(nil).PostBucketsExecute), arg0)
}

4
internal/mock/gen.go Normal file
View File

@ -0,0 +1,4 @@
package mock
//go:generate mockgen -package mock -destination api_bucket_schemas.gen.go github.com/influxdata/influx-cli/v2/internal/api BucketSchemasApi
//go:generate mockgen -package mock -destination api_buckets.gen.go github.com/influxdata/influx-cli/v2/internal/api BucketsApi

20
internal/params.go Normal file
View File

@ -0,0 +1,20 @@
package internal
import (
"github.com/influxdata/influx-cli/v2/pkg/influxid"
)
type OrgParams struct {
OrgID influxid.ID
OrgName string
}
type BucketParams struct {
BucketID influxid.ID
BucketName string
}
type OrgBucketParams struct {
OrgParams
BucketParams
}