diff --git a/.gitignore b/.gitignore index 9fd9a4d..5adbe0d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.iml .idea/** apiserver/.openapi-generator/** -apiserver/api/** \ No newline at end of file +apiserver/api/** +apiserver/*_service.go \ No newline at end of file diff --git a/README.md b/README.md index a49a42f..98889af 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ This app collects the data from configurable Hailo FDS endpoints. For each endpo ## Configuration -The app needs environment variables and database tables for configuration. +The app needs environment variables and database tables for configuration. To edit the database tables the app provides an own API access. ### Eliona ### @@ -58,31 +58,13 @@ export LOG_LEVEL=debug # optionally, default is 'info' The app requires configuration data that remains in the database. To do this, the app creates its own database schema `hailo` during initialization. Some data in this schema should be made editable by Eliona frontend. This allows the app to be configured by the user without direct database access. +To modify and handle the configuration data the Hailo app provides an API access. Have a look at the [API specification](https://eliona-smart-building-assistant.github.io/open-api-docs/?https://raw.githubusercontent.com/eliona-smart-building-assistant/hailo-app/develop/openapi.yaml) ([openapi.yaml](https://raw.githubusercontent.com/eliona-smart-building-assistant/hailo-app/develop/openapi.yaml)) how the configuration tables should be used. The API is available at `http://servername:80/v1`. The port can be configured with the `API_SERVER_PORT` environment variable. + #### hailo.config -The database table `hailo.config` contains Hailo FDS endpoints. Each row stands for one endpoint with configurable timeouts and polling intervals. This table should be editable by the Eliona frontend. The table is filled during the initialization to demonstrate the configuration. This demo data contains no real endpoint and must be change for proper working. - -| Column | Description | -|-------------------|:-----------------------------------------------------------------------------------| -| `app_id` | Id to identify the configured endpoint (automatically by sequence) | -| `config` | JSON string to configure the endpoint (see below) | -| `enable` | Flag to enable or disable the endpoint | -| `description` | Description of the endpoint (optional) | -| `asset_id` | Id of an parent asset with groups all device assets (optional) | -| `interval_sec` | Interval in seconds for collecting data from endpoint | -| `auth_timeout` | Timeout in seconds for authentication server (default `5`s) | -| `request_timeout` | Timeout in seconds for FDS server (default `120`s) | -| `active` | Set to `true` by the app when running and to `false` when app is stopped | -| `proj_ids` | List of Eliona project ids for which this endpoint should collect data (see below) | - -The `config` column have to contain a JSON to configure the Hailo FDS endpoint: - - { - "username": "Login for auth endpoint" - "password": "Password for auth endpoint" - "auth_server": "Url to Hailo auth endpoint" - "fds_server": "Url to Hailo FDS endpoint" - } +The database table `hailo.config` contains Hailo FDS endpoints. Each row stands for one endpoint with configurable timeouts and polling intervals. This table should be editable by the Eliona frontend. The table is filled during the initialization to demonstrate the configuration. This demo data contains no real endpoint and must be change for proper working. + +For a detailed description have a look at the [API specification](https://eliona-smart-building-assistant.github.io/open-api-docs/?https://raw.githubusercontent.com/eliona-smart-building-assistant/hailo-app/develop/openapi.yaml) ([openapi.yaml](https://raw.githubusercontent.com/eliona-smart-building-assistant/hailo-app/develop/openapi.yaml)). Insert in the `proj_ids` column all Eliona project ids for which the endpoint should create assets and collect data from all Hailo smart devices. For example, if the column contains `{1, 99}` the app does the following: @@ -92,16 +74,9 @@ Insert in the `proj_ids` column all Eliona project ids for which the endpoint sh #### hailo.asset -The table `hailo.asset` maps each Hailo smart device to an Eliona asset. For different Eliona projects different assets are used. The app collect and writes data separate for each configured project (see column `proj_ids` above). +The table `hailo.asset` maps each Hailo smart device to an Eliona asset. For different Eliona projects different assets are used. The app collect and writes data separate for each configured project (see column `proj_ids` above). The mapping is created automatically by the app. So this table does not necessarily have to be editable via the frontend or displayed in the frontend. -The mapping is created automatically by the app. So this table does not necessarily have to be editable via the frontend or displayed in the frontend. - -| Column | Description | -|-------------|:----------------------------------------------------------------------------------| -| `config_id` | References the configured endpoint (column `app_id` in table `hailo.config`) | -| `device_id` | References to the Hailo smart device (`device_id` from Hailo Smart Hub) | -| `asset_id` | References the asset id from Eliona an maps the device id to an Eliona asset | -| `proj_id` | The project id for which the Eliona asset is created (see column `proj_ids` above | +For a detailed description have a look at the [API specification](https://eliona-smart-building-assistant.github.io/open-api-docs/?https://raw.githubusercontent.com/eliona-smart-building-assistant/hailo-app/develop/openapi.yaml) ([openapi.yaml](https://raw.githubusercontent.com/eliona-smart-building-assistant/hailo-app/develop/openapi.yaml)). If specification of a Hailo smart device is read (at the first time or if new devices are added later) the app looks if there is already a mapping. If so, the app uses the mapped asset id for writing the data. If not, the app creates a new Eliona asset or updates an existing one and inserts the mapping in this table for further use. @@ -120,6 +95,24 @@ Versions of this app prior 2.0 use different mapping of assets and Hailo smart d where asset_type like 'Hailo%' +## Generation and Implementation ## + +The Hailo app uses generators to create API server capabilities and database access. + +For the API server the [OpenAPI Generator](https://openapi-generator.tech/docs/generators/openapi-yaml) for go-server is used. The easiest way to generate the server files is to use one of the predefined generation script which use the OpenAPI Generator Docker image. + +``` +.\generate-api-server.cmd # Windows +./generate-api-server.sh # Linux +``` + +For the database access [SQLBoiler](https://github.com/volatiletech/sqlboiler) is used. The easiest way to generate the database files is to use one of the predefined generation script which use the SQLBoiler implementation. Please note that the database connection in the `sqlboiler.toml` file have to be configured. + +``` +.\generate-db.cmd # Windows +./generate-db.sh # Linux +``` + ## API Reference The hailo app writes data for each Hailo smart device. The data is structured into different subtypes of Eliona assets. See [eliona/heaps.go](eliona/heaps.go) for details. The following subtypes are defined: diff --git a/apiserver/.openapi-generator-ignore b/apiserver/.openapi-generator-ignore index aef1497..b7ec3fe 100644 --- a/apiserver/.openapi-generator-ignore +++ b/apiserver/.openapi-generator-ignore @@ -6,6 +6,4 @@ # If the API changes please remove these lines and merge the generated files with the existing ones. api/** -#api_asset_mapping_service.go -#api_configuration_service.go README.md \ No newline at end of file diff --git a/apiserver/api.go b/apiserver/api.go index 0765b55..fcdea15 100644 --- a/apiserver/api.go +++ b/apiserver/api.go @@ -18,16 +18,18 @@ import ( // The AssetMappingApiRouter implementation should parse necessary information from the http request, // pass the data to a AssetMappingApiServicer to perform the required actions, then write the service results to the http response. type AssetMappingApiRouter interface { - GetAssetMappingsByConfig(http.ResponseWriter, *http.Request) + GetAssetMappings(http.ResponseWriter, *http.Request) } // ConfigurationApiRouter defines the required methods for binding the api requests to a responses for the ConfigurationApi // The ConfigurationApiRouter implementation should parse necessary information from the http request, // pass the data to a ConfigurationApiServicer to perform the required actions, then write the service results to the http response. type ConfigurationApiRouter interface { - GetConfiguration(http.ResponseWriter, *http.Request) + DeleteConfigurationById(http.ResponseWriter, *http.Request) + GetConfigurationById(http.ResponseWriter, *http.Request) GetConfigurations(http.ResponseWriter, *http.Request) - PutConfiguration(http.ResponseWriter, *http.Request) + PostConfiguration(http.ResponseWriter, *http.Request) + PutConfigurationById(http.ResponseWriter, *http.Request) } // AssetMappingApiServicer defines the api actions for the AssetMappingApi service @@ -35,7 +37,7 @@ type ConfigurationApiRouter interface { // while the service implementation can be ignored with the .openapi-generator-ignore file // and updated with the logic required for the API. type AssetMappingApiServicer interface { - GetAssetMappingsByConfig(context.Context, int32) (ImplResponse, error) + GetAssetMappings(context.Context, int64) (ImplResponse, error) } // ConfigurationApiServicer defines the api actions for the ConfigurationApi service @@ -43,7 +45,9 @@ type AssetMappingApiServicer interface { // while the service implementation can be ignored with the .openapi-generator-ignore file // and updated with the logic required for the API. type ConfigurationApiServicer interface { - GetConfiguration(context.Context, int32) (ImplResponse, error) + DeleteConfigurationById(context.Context, int64) (ImplResponse, error) + GetConfigurationById(context.Context, int64) (ImplResponse, error) GetConfigurations(context.Context) (ImplResponse, error) - PutConfiguration(context.Context, int32) (ImplResponse, error) + PostConfiguration(context.Context, Configuration) (ImplResponse, error) + PutConfigurationById(context.Context, int64, Configuration) (ImplResponse, error) } diff --git a/apiserver/api_asset_mapping.go b/apiserver/api_asset_mapping.go index 27cfcb9..b6ef99d 100644 --- a/apiserver/api_asset_mapping.go +++ b/apiserver/api_asset_mapping.go @@ -48,23 +48,23 @@ func NewAssetMappingApiController(s AssetMappingApiServicer, opts ...AssetMappin func (c *AssetMappingApiController) Routes() Routes { return Routes{ { - "GetAssetMappingsByConfig", + "GetAssetMappings", strings.ToUpper("Get"), - "/v1/asset/mapping/", - c.GetAssetMappingsByConfig, + "/v1/asset-mappings/", + c.GetAssetMappings, }, } } -// GetAssetMappingsByConfig - -func (c *AssetMappingApiController) GetAssetMappingsByConfig(w http.ResponseWriter, r *http.Request) { +// GetAssetMappings - +func (c *AssetMappingApiController) GetAssetMappings(w http.ResponseWriter, r *http.Request) { query := r.URL.Query() - configIdParam, err := parseInt32Parameter(query.Get("config-id"), false) + configIdParam, err := parseInt64Parameter(query.Get("config-id"), false) if err != nil { c.errorHandler(w, r, &ParsingError{Err: err}, nil) return } - result, err := c.service.GetAssetMappingsByConfig(r.Context(), configIdParam) + result, err := c.service.GetAssetMappings(r.Context(), configIdParam) // If an error occurred, encode the error with the status code if err != nil { c.errorHandler(w, r, err, &result) diff --git a/apiserver/api_asset_mapping_service.go b/apiserver/api_asset_mapping_service.go deleted file mode 100644 index 48022cc..0000000 --- a/apiserver/api_asset_mapping_service.go +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Hailo app API - * - * API to access and configure the Hailo app - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package apiserver - -import ( - "context" - "errors" - "net/http" -) - -// AssetMappingApiService is a service that implements the logic for the AssetMappingApiServicer -// This service should implement the business logic for every endpoint for the AssetMappingApi API. -// Include any external packages or services that will be required by this service. -type AssetMappingApiService struct { -} - -// NewAssetMappingApiService creates a default api service -func NewAssetMappingApiService() AssetMappingApiServicer { - return &AssetMappingApiService{} -} - -// GetAssetMappingsByConfig - -func (s *AssetMappingApiService) GetAssetMappingsByConfig(ctx context.Context, configId int32) (ImplResponse, error) { - // TODO - update GetAssetMappingsByConfig with the required logic for this service method. - // Add api_asset_mapping_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - //TODO: Uncomment the next line to return response Response(200, []AssetMapping{}) or use other options such as http.Ok ... - //return Response(200, []AssetMapping{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetAssetMappingsByConfig method not implemented") -} diff --git a/apiserver/api_configuration.go b/apiserver/api_configuration.go index a2ff2dd..270c24b 100644 --- a/apiserver/api_configuration.go +++ b/apiserver/api_configuration.go @@ -10,6 +10,7 @@ package apiserver import ( + "encoding/json" "net/http" "strings" @@ -50,36 +51,68 @@ func NewConfigurationApiController(s ConfigurationApiServicer, opts ...Configura func (c *ConfigurationApiController) Routes() Routes { return Routes{ { - "GetConfiguration", + "DeleteConfigurationById", + strings.ToUpper("Delete"), + "/v1/configs/{config-id}", + c.DeleteConfigurationById, + }, + { + "GetConfigurationById", strings.ToUpper("Get"), - "/v1/config/{config-id}", - c.GetConfiguration, + "/v1/configs/{config-id}", + c.GetConfigurationById, }, { "GetConfigurations", strings.ToUpper("Get"), - "/v1/config", + "/v1/configs", c.GetConfigurations, }, { - "PutConfiguration", + "PostConfiguration", + strings.ToUpper("Post"), + "/v1/configs", + c.PostConfiguration, + }, + { + "PutConfigurationById", strings.ToUpper("Put"), - "/v1/config/{config-id}", - c.PutConfiguration, + "/v1/configs/{config-id}", + c.PutConfigurationById, }, } } -// GetConfiguration - Get FDS endpoint -func (c *ConfigurationApiController) GetConfiguration(w http.ResponseWriter, r *http.Request) { +// DeleteConfigurationById - Deletes a FDS endpoint +func (c *ConfigurationApiController) DeleteConfigurationById(w http.ResponseWriter, r *http.Request) { + params := mux.Vars(r) + configIdParam, err := parseInt64Parameter(params["config-id"], true) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + + result, err := c.service.DeleteConfigurationById(r.Context(), configIdParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) + +} + +// GetConfigurationById - Get FDS endpoint +func (c *ConfigurationApiController) GetConfigurationById(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) - configIdParam, err := parseInt32Parameter(params["config-id"], true) + configIdParam, err := parseInt64Parameter(params["config-id"], true) if err != nil { c.errorHandler(w, r, &ParsingError{Err: err}, nil) return } - result, err := c.service.GetConfiguration(r.Context(), configIdParam) + result, err := c.service.GetConfigurationById(r.Context(), configIdParam) // If an error occurred, encode the error with the status code if err != nil { c.errorHandler(w, r, err, &result) @@ -103,16 +136,51 @@ func (c *ConfigurationApiController) GetConfigurations(w http.ResponseWriter, r } -// PutConfiguration - Creates or update an FDS endpoint -func (c *ConfigurationApiController) PutConfiguration(w http.ResponseWriter, r *http.Request) { +// PostConfiguration - Creates an FDS endpoint +func (c *ConfigurationApiController) PostConfiguration(w http.ResponseWriter, r *http.Request) { + configurationParam := Configuration{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&configurationParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertConfigurationRequired(configurationParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.PostConfiguration(r.Context(), configurationParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) + +} + +// PutConfigurationById - Updates an FDS endpoint +func (c *ConfigurationApiController) PutConfigurationById(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) - configIdParam, err := parseInt32Parameter(params["config-id"], true) + configIdParam, err := parseInt64Parameter(params["config-id"], true) if err != nil { c.errorHandler(w, r, &ParsingError{Err: err}, nil) return } - result, err := c.service.PutConfiguration(r.Context(), configIdParam) + configurationParam := Configuration{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&configurationParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertConfigurationRequired(configurationParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.PutConfigurationById(r.Context(), configIdParam, configurationParam) // If an error occurred, encode the error with the status code if err != nil { c.errorHandler(w, r, err, &result) diff --git a/apiserver/api_configuration_service.go b/apiserver/api_configuration_service.go deleted file mode 100644 index eff1df9..0000000 --- a/apiserver/api_configuration_service.go +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Hailo app API - * - * API to access and configure the Hailo app - * - * API version: 1.0.0 - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - -package apiserver - -import ( - "context" - "errors" - "net/http" -) - -// ConfigurationApiService is a service that implements the logic for the ConfigurationApiServicer -// This service should implement the business logic for every endpoint for the ConfigurationApi API. -// Include any external packages or services that will be required by this service. -type ConfigurationApiService struct { -} - -// NewConfigurationApiService creates a default api service -func NewConfigurationApiService() ConfigurationApiServicer { - return &ConfigurationApiService{} -} - -// GetConfiguration - Get FDS endpoint -func (s *ConfigurationApiService) GetConfiguration(ctx context.Context, configId int32) (ImplResponse, error) { - // TODO - update GetConfiguration with the required logic for this service method. - // Add api_configuration_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - //TODO: Uncomment the next line to return response Response(200, Configuration{}) or use other options such as http.Ok ... - //return Response(200, Configuration{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetConfiguration method not implemented") -} - -// GetConfigurations - Get all FDS endpoints -func (s *ConfigurationApiService) GetConfigurations(ctx context.Context) (ImplResponse, error) { - // TODO - update GetConfigurations with the required logic for this service method. - // Add api_configuration_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - //TODO: Uncomment the next line to return response Response(200, []Configuration{}) or use other options such as http.Ok ... - //return Response(200, []Configuration{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetConfigurations method not implemented") -} - -// PutConfiguration - Creates or update an FDS endpoint -func (s *ConfigurationApiService) PutConfiguration(ctx context.Context, configId int32) (ImplResponse, error) { - // TODO - update PutConfiguration with the required logic for this service method. - // Add api_configuration_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - //TODO: Uncomment the next line to return response Response(200, Configuration{}) or use other options such as http.Ok ... - //return Response(200, Configuration{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("PutConfiguration method not implemented") -} diff --git a/apiserver/model_asset_mapping.go b/apiserver/model_asset_mapping.go index ecc4a1e..30921a5 100644 --- a/apiserver/model_asset_mapping.go +++ b/apiserver/model_asset_mapping.go @@ -13,16 +13,16 @@ package apiserver type AssetMapping struct { // References the configured endpoint (see `Configuration`) - ConfigId int32 `json:"config_id,omitempty"` + ConfigId int32 `json:"configId,omitempty"` // References to the Hailo smart device (internal id from Hailo FDS for this device) - DeviceId string `json:"device_id,omitempty"` + DeviceId string `json:"deviceId,omitempty"` // The project id for which the Eliona asset is created (see `proj_ids` in `Configuration`) - ProjId string `json:"proj_id,omitempty"` + ProjId string `json:"projId,omitempty"` // References the asset id in Eliona which is automatically created by the app - AssetId int32 `json:"asset_id,omitempty"` + AssetId int32 `json:"assetId,omitempty"` } // AssertAssetMappingRequired checks if the required fields are not zero-ed diff --git a/apiserver/model_configuration.go b/apiserver/model_configuration.go index 66f0f2a..4c7da58 100644 --- a/apiserver/model_configuration.go +++ b/apiserver/model_configuration.go @@ -13,59 +13,50 @@ package apiserver type Configuration struct { // Internal identifier for the configured endpoint (created automatically). This identifier have to use always if you remove or update existing configured endpoints. - Id int32 `json:"id,omitempty"` + Id *int64 `json:"id,omitempty"` // Login for authentication endpoint - Username string `json:"username"` + Username *string `json:"username,omitempty"` // Password for authentication endpoint - Password string `json:"password"` + Password *string `json:"password,omitempty"` // Url to Hailo authentication endpoint - AuthServer string `json:"auth_server"` + AuthServer *string `json:"authServer,omitempty"` // Url to Hailo FDS endpoint - FdsServer string `json:"fds_server"` + FdsServer *string `json:"fdsServer,omitempty"` // Flag to enable or disable the endpoint - Enable bool `json:"enable,omitempty"` + Enable *bool `json:"enable,omitempty"` // Description of the endpoint - Description string `json:"description,omitempty"` + Description *string `json:"description,omitempty"` // Id of an parent asset with groups all device assets - AssetId int32 `json:"asset_id,omitempty"` + AssetId *int32 `json:"assetId,omitempty"` // Interval in seconds for collecting data from endpoint - IntervalSec int32 `json:"interval_sec,omitempty"` + IntervalSec int32 `json:"intervalSec,omitempty"` // Timeout in seconds for authentication server - AuthTimeout int32 `json:"auth_timeout,omitempty"` + AuthTimeout int32 `json:"authTimeout,omitempty"` // Timeout in seconds for FDS server - RequestTimeout int32 `json:"request_timeout,omitempty"` + RequestTimeout int32 `json:"requestTimeout,omitempty"` + + // Timeout for inactivity + InactiveTimeout int32 `json:"inactiveTimeout,omitempty"` // Set to `true` by the app when running and to `false` when app is stopped - Active bool `json:"active,omitempty"` + Active *bool `json:"active,omitempty"` // List of Eliona project ids for which this endpoint should collect data. For each pair of project id and Hailo smart device identifier found in the configured endpoint an asset is automatically created in Eliona. This mapping of project id and device id on the one hand and the Eliona asset id on the other hand is separately stored by the Hailo app (see `AssetMapping`). - ProjIds []string `json:"proj_ids,omitempty"` + ProjIds *[]string `json:"projIds,omitempty"` } // AssertConfigurationRequired checks if the required fields are not zero-ed func AssertConfigurationRequired(obj Configuration) error { - elements := map[string]interface{}{ - "username": obj.Username, - "password": obj.Password, - "auth_server": obj.AuthServer, - "fds_server": obj.FdsServer, - } - for name, el := range elements { - if isZero := IsZeroValue(el); isZero { - return &RequiredError{Field: name} - } - } - return nil } diff --git a/apiservices/api_asset_mapping_service.go b/apiservices/api_asset_mapping_service.go new file mode 100644 index 0000000..45f90ba --- /dev/null +++ b/apiservices/api_asset_mapping_service.go @@ -0,0 +1,45 @@ +// This file is part of the eliona project. +// Copyright © 2022 LEICOM iTEC AG. All Rights Reserved. +// ______ _ _ +// | ____| (_) +// | |__ | |_ ___ _ __ __ _ +// | __| | | |/ _ \| '_ \ / _` | +// | |____| | | (_) | | | | (_| | +// |______|_|_|\___/|_| |_|\__,_| +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package apiservices + +import ( + "context" + "errors" + "hailo/apiserver" + "net/http" +) + +// AssetMappingApiService is a service that implements the logic for the AssetMappingApiServicer +// This service should implement the business logic for every endpoint for the AssetMappingApi API. +// Include any external packages or services that will be required by this service. +type AssetMappingApiService struct { +} + +// NewAssetMappingApiService creates a default api service +func NewAssetMappingApiService() apiserver.AssetMappingApiServicer { + return &AssetMappingApiService{} +} + +// GetAssetMappings - +func (s *AssetMappingApiService) GetAssetMappings(ctx context.Context, configId int64) (apiserver.ImplResponse, error) { + // TODO - update GetAssetMappings with the required logic for this service method. + // Add api_asset_mapping_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + //TODO: Uncomment the next line to return response Response(200, []AssetMapping{}) or use other options such as http.Ok ... + //return Response(200, []AssetMapping{}), nil + + return apiserver.Response(http.StatusNotImplemented, nil), errors.New("GetAssetMappings method not implemented") +} diff --git a/apiservices/api_configuration_service.go b/apiservices/api_configuration_service.go new file mode 100644 index 0000000..ca82e1f --- /dev/null +++ b/apiservices/api_configuration_service.go @@ -0,0 +1,85 @@ +// This file is part of the eliona project. +// Copyright © 2022 LEICOM iTEC AG. All Rights Reserved. +// ______ _ _ +// | ____| (_) +// | |__ | |_ ___ _ __ __ _ +// | __| | | |/ _ \| '_ \ / _` | +// | |____| | | (_) | | | | (_| | +// |______|_|_|\___/|_| |_|\__,_| +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package apiservices + +import ( + "context" + "hailo/apiserver" + "hailo/conf" + "net/http" +) + +// ConfigurationApiService is a service that implements the logic for the ConfigurationApiServicer +// This service should implement the business logic for every endpoint for the ConfigurationApi API. +// Include any external packages or services that will be required by this service. +type ConfigurationApiService struct { +} + +// NewConfigurationApiService creates a default api service +func NewConfigurationApiService() apiserver.ConfigurationApiServicer { + return &ConfigurationApiService{} +} + +// DeleteConfigurationById - Deletes a FDS endpoint +func (s *ConfigurationApiService) DeleteConfigurationById(ctx context.Context, configId int64) (apiserver.ImplResponse, error) { + count, err := conf.DeleteConfig(ctx, configId) + if err != nil { + return apiserver.ImplResponse{Code: http.StatusInternalServerError}, err + } + if count == 0 { + return apiserver.ImplResponse{Code: http.StatusNotFound}, err + } + return apiserver.ImplResponse{Code: http.StatusNoContent}, err +} + +// GetConfigurationById - Get FDS endpoint +func (s *ConfigurationApiService) GetConfigurationById(ctx context.Context, configId int64) (apiserver.ImplResponse, error) { + config, err := conf.GetConfig(context.Background(), configId) + if err != nil { + return apiserver.ImplResponse{Code: http.StatusInternalServerError}, err + } + if config == nil { + return apiserver.ImplResponse{Code: http.StatusNotFound}, err + } + return apiserver.Response(http.StatusOK, config), nil +} + +// GetConfigurations - Get all FDS endpoints +func (s *ConfigurationApiService) GetConfigurations(ctx context.Context) (apiserver.ImplResponse, error) { + configs, err := conf.GetConfigs(ctx) + if err != nil { + return apiserver.ImplResponse{Code: http.StatusInternalServerError}, err + } + return apiserver.Response(http.StatusOK, configs), nil +} + +// PostConfiguration - Creates an FDS endpoint +func (s *ConfigurationApiService) PostConfiguration(ctx context.Context, config apiserver.Configuration) (apiserver.ImplResponse, error) { + insertedConfig, err := conf.InsertConfig(ctx, config) + if err != nil { + return apiserver.ImplResponse{Code: http.StatusInternalServerError}, err + } + return apiserver.Response(http.StatusCreated, insertedConfig), nil +} + +// PutConfigurationById - Upserts an FDS endpoint +func (s *ConfigurationApiService) PutConfigurationById(ctx context.Context, configId int64, config apiserver.Configuration) (apiserver.ImplResponse, error) { + upsertedConfig, err := conf.UpsertConfigById(ctx, configId, config) + if err != nil { + return apiserver.ImplResponse{Code: http.StatusInternalServerError}, err + } + return apiserver.Response(http.StatusCreated, upsertedConfig), nil +} diff --git a/apiservices/example_requests_configuration.http b/apiservices/example_requests_configuration.http new file mode 100644 index 0000000..bf49a95 --- /dev/null +++ b/apiservices/example_requests_configuration.http @@ -0,0 +1,47 @@ +### Get configs +GET http://localhost:8033/v1/configs + +### Get config +GET http://localhost:8033/v1/configs/1 + +### Put config (insert without id) +PUT http://localhost:8033/v1/configs +Content-Type: application/json; charset=UTF-8 + +{ + "username": "xxx", + "password": "yyy", + "authServer": "https://7th5pn7m33.execute-api.eu-central-1.amazonaws.com", + "fdsServer": "https://fmpxh1uxl6.execute-api.eu-central-1.amazonaws.com/fds/v1", + "enable": true, + "description": "Hailo FDS demo configuration. Please change to your hailo server endpoints and authentication.", + "intervalSec": 60, + "authTimeout": 5, + "requestTimeout": 120, + "inactiveTimeout": 43200, + "projIds": [ + "99" + ] +} + +### Put update (with id) +PUT http://localhost:8033/v1/configs +Content-Type: application/json; charset=UTF-8 + +{ + "id": 6, + "username": "***", + "password": "***", + "authServer": "https://7th5pn7m33.execute-api.eu-central-1.amazonaws.com", + "fdsServer": "https://fmpxh1uxl6.execute-api.eu-central-1.amazonaws.com/fds/v1", + "enable": true, + "description": "Hailo FDS demo configuration. Please change to your hailo server endpoints and authentication.", + "intervalSec": 60, + "authTimeout": 5, + "requestTimeout": 120, + "inactiveTimeout": 43200, + "projIds": [ + "99" + ] +} + diff --git a/app.go b/app.go index 54fa044..70f966d 100644 --- a/app.go +++ b/app.go @@ -16,9 +16,11 @@ package main import ( + "context" "github.com/eliona-smart-building-assistant/go-utils/common" "github.com/eliona-smart-building-assistant/go-utils/log" "hailo/apiserver" + "hailo/apiservices" "hailo/conf" "hailo/eliona" "hailo/hailo" @@ -34,33 +36,33 @@ func collectData() { // Check if import or update of assets is requested // Load all configured configs from table hailo.config. - configs := conf.GetConfigs() - if len(configs) <= 0 { - log.Fatal("Hailo", "Couldn't read config from configured database.") + configs, err := conf.GetConfigs(context.Background()) + if len(configs) <= 0 || err != nil { + log.Fatal("Hailo", "Couldn't read config from configured database: %v", err) } // Start collection data for each config for _, config := range configs { // Skip config if disabled and set inactive - if !config.Enable { - if config.Active { - conf.SetConfigActive(config.Id, false) + if !conf.IsConfigEnabled(config) { + if conf.IsConfigActive(config) { + conf.SetConfigActiveState(context.Background(), config, false) } continue } // Signals, that this config is active - if !config.Active { - conf.SetConfigActive(config.Id, true) + if !conf.IsConfigActive(config) { + conf.SetConfigActiveState(context.Background(), config, true) log.Info("Hailo", "Collecting %d initialized with config:\n"+ "FDS Fds Endpoint: %s\n"+ "FDS Fds Auth Server: %s\n"+ "Auth Timeout: %d\n"+ "Request Timeout: %d", config.Id, - config.FdsConfig.FdsServer, - config.FdsConfig.AuthServer, + config.FdsServer, + config.AuthServer, config.AuthTimeout, config.RequestTimeout) } @@ -88,8 +90,8 @@ func collectData() { // The API endpoints are defined in the openapi.yaml file func listenApiRequests() { err := http.ListenAndServe(":"+common.Getenv("API_SERVER_PORT", "80"), apiserver.NewRouter( - apiserver.NewAssetMappingApiController(apiserver.NewAssetMappingApiService()), - apiserver.NewConfigurationApiController(apiserver.NewConfigurationApiService()), + apiserver.NewAssetMappingApiController(apiservices.NewAssetMappingApiService()), + apiserver.NewConfigurationApiController(apiservices.NewConfigurationApiService()), )) log.Fatal("Hailo", "Error in API Server: %v", err) } @@ -97,7 +99,7 @@ func listenApiRequests() { // collectDataForConfig reads specification of all devices in the given connection. For all devices found asset // data is written. In case of stations (group multiple component devices) data for each component is read and // written. -func collectDataForConfig(config conf.Config) { +func collectDataForConfig(config apiserver.Configuration) { // Read specs from Hailo FDS specs, err := hailo.GetSpecs(config) diff --git a/conf/conf.go b/conf/conf.go index fbbe8f9..6bb7876 100644 --- a/conf/conf.go +++ b/conf/conf.go @@ -16,8 +16,14 @@ package conf import ( + "context" + "github.com/eliona-smart-building-assistant/go-utils/common" "github.com/eliona-smart-building-assistant/go-utils/db" - "github.com/eliona-smart-building-assistant/go-utils/log" + "github.com/volatiletech/null/v8" + "github.com/volatiletech/sqlboiler/v4/boil" + "github.com/volatiletech/sqlboiler/v4/types" + "hailo/apiserver" + dbhailo "hailo/db/hailo" ) const DefaultInactiveTimeout = 60 * 60 * 24 // time until set a container to inactive (sec) @@ -29,76 +35,172 @@ type FdsConfig struct { AuthServer string `json:"auth_server"` } -type Config struct { - Id int - FdsConfig FdsConfig - Enable bool - Active bool - IntervalSec int - AuthTimeout int - RequestTimeout int - InactiveTimeout int - ProjectIds []string -} - -// GetConfigs reads all configured endpoints to a Hailo Digital Hub -func GetConfigs() []Config { - channel := make(chan Config) - var configurations []Config - go func() { - _ = db.Query(db.Pool(), "select app_id, config, enable, active, interval_sec, auth_timeout, request_timeout, inactive_timeout, proj_ids from hailo.config", channel) - }() - for configuration := range channel { - if configuration.InactiveTimeout == 0 { - configuration.InactiveTimeout = DefaultInactiveTimeout - } - configurations = append(configurations, configuration) +// GetConfigs reads all configured endpoints for a Hailo Digital Hub +func GetConfigs(ctx context.Context) ([]apiserver.Configuration, error) { + dbConfigs, err := dbhailo.Configs().All(ctx, db.Database()) + if err != nil { + return nil, err + } + var apiConfigs []apiserver.Configuration + for _, dbConfig := range dbConfigs { + apiConfigs = append(apiConfigs, *apiConfigFromDbConfig(dbConfig)) } - return configurations + return apiConfigs, nil +} + +// InsertConfig inserts or updates +func InsertConfig(ctx context.Context, config apiserver.Configuration) (apiserver.Configuration, error) { + dbConfig := dbConfigFromApiConfig(&config) + err := dbConfig.Insert(ctx, db.Database(), boil.Blacklist(dbhailo.ConfigColumns.AppID)) + if err != nil { + return apiserver.Configuration{}, err + } + config.Id = &dbConfig.AppID + return config, err +} + +// UpsertConfigById inserts or updates +func UpsertConfigById(ctx context.Context, configId int64, config apiserver.Configuration) (apiserver.Configuration, error) { + dbConfig := dbConfigFromApiConfig(&config) + dbConfig.AppID = configId + err := dbConfig.Upsert(ctx, db.Database(), true, + []string{dbhailo.ConfigColumns.AppID}, + boil.Blacklist(dbhailo.ConfigColumns.AppID), + boil.Infer(), + ) + config.Id = &dbConfig.AppID + return config, err +} + +func apiConfigFromDbConfig(dbConfig *dbhailo.Config) *apiserver.Configuration { + var apiConfig apiserver.Configuration + apiConfig.Id = &dbConfig.AppID + apiConfig.AssetId = dbConfig.AssetID.Ptr() + apiConfig.Enable = dbConfig.Enable.Ptr() + apiConfig.Description = dbConfig.Description.Ptr() + apiConfig.InactiveTimeout = getInactiveTimeout(dbConfig) + var fdsConfig FdsConfig + _ = dbConfig.Config.Unmarshal(&fdsConfig) + apiConfig.Username = &fdsConfig.Name + apiConfig.Password = &fdsConfig.Password + apiConfig.AuthServer = &fdsConfig.AuthServer + apiConfig.FdsServer = &fdsConfig.FdsServer + apiConfig.AuthTimeout = dbConfig.AuthTimeout + apiConfig.IntervalSec = dbConfig.IntervalSec + apiConfig.RequestTimeout = dbConfig.RequestTimeout + apiConfig.ProjIds = common.Ptr[[]string](dbConfig.ProjIds) + return &apiConfig +} + +func dbConfigFromApiConfig(apiConfig *apiserver.Configuration) *dbhailo.Config { + var dbConfig dbhailo.Config + dbConfig.AppID = null.Int64FromPtr(apiConfig.Id).Int64 + dbConfig.AssetID = null.Int32FromPtr(apiConfig.AssetId) + dbConfig.Enable = null.BoolFromPtr(apiConfig.Enable) + dbConfig.Description = null.StringFromPtr(apiConfig.Description) + dbConfig.InactiveTimeout = null.Int32From(apiConfig.InactiveTimeout) + dbConfig.AuthTimeout = apiConfig.AuthTimeout + dbConfig.IntervalSec = apiConfig.IntervalSec + dbConfig.RequestTimeout = apiConfig.RequestTimeout + if apiConfig.ProjIds != nil { + dbConfig.ProjIds = *apiConfig.ProjIds + } + var fdsConfig types.JSON + _ = fdsConfig.Marshal(FdsConfig{ + Name: null.StringFromPtr(apiConfig.Username).String, + Password: null.StringFromPtr(apiConfig.Password).String, + AuthServer: null.StringFromPtr(apiConfig.AuthServer).String, + FdsServer: null.StringFromPtr(apiConfig.FdsServer).String, + }) + dbConfig.Config = fdsConfig + return &dbConfig +} + +func getInactiveTimeout(config *dbhailo.Config) int32 { + if config.InactiveTimeout.Valid { + return config.InactiveTimeout.Int32 + } else { + return DefaultInactiveTimeout + } +} + +// GetConfig reads configured endpoints to a Hailo Digital Hub +func GetConfig(ctx context.Context, configId int64) (*apiserver.Configuration, error) { + dbConfigs, err := dbhailo.Configs(dbhailo.ConfigWhere.AppID.EQ(configId)).All(ctx, db.Database()) + if err != nil { + return nil, err + } + if len(dbConfigs) == 0 { + return nil, err + } + return apiConfigFromDbConfig(dbConfigs[0]), nil +} + +// DeleteConfig reads configured endpoints to a Hailo Digital Hub +func DeleteConfig(ctx context.Context, configId int64) (int64, error) { + return dbhailo.Configs(dbhailo.ConfigWhere.AppID.EQ(configId)).DeleteAll(ctx, db.Database()) } // BuildFdsConfig create a config object with the given parameters and default values -func BuildFdsConfig(authServer string, username string, password string, fdsEndpoint string) Config { - config := Config{ - FdsConfig: FdsConfig{ - Name: username, - Password: password, - FdsServer: fdsEndpoint, - AuthServer: authServer, - }, - Enable: true, +func BuildFdsConfig(authServer string, username string, password string, fdsEndpoint string) apiserver.Configuration { + config := apiserver.Configuration{ + Username: &username, + Password: &password, + FdsServer: &fdsEndpoint, + AuthServer: &authServer, + Enable: common.Ptr(true), AuthTimeout: 5, RequestTimeout: 60, } return config } -func GetAssetId(confId int, projId string, deviceId string) *int32 { - assetId, err := db.QuerySingleRow[*int32](db.Pool(), "select asset_id from hailo.asset where config_id = $1 and proj_id = $2 and device_id = $3", confId, projId, deviceId) - if err != nil { - log.Error("Hailo", "Error getting asset id: %v", err) +func GetAssetId(ctx context.Context, config apiserver.Configuration, projId string, deviceId string) (*int32, error) { + dbAssets, err := dbhailo.Assets( + dbhailo.AssetWhere.ConfigID.EQ(null.Int64FromPtr(config.Id).Int64), + dbhailo.AssetWhere.ProjID.EQ(projId), + dbhailo.AssetWhere.DeviceID.EQ(deviceId), + ).All(ctx, db.Database()) + if err != nil || len(dbAssets) == 0 { + return nil, err } - return assetId + return common.Ptr(dbAssets[0].AssetID), nil } -func InsertAsset(confId int, projId string, deviceId string, assetId int32) error { - return db.Exec(db.Pool(), "insert into hailo.asset (config_id, device_id, proj_id, asset_id) values ($1, $2, $3, $4)", - confId, - deviceId, - projId, - assetId) +func InsertAsset(ctx context.Context, config apiserver.Configuration, projId string, deviceId string, assetId int32) error { + var dbAsset dbhailo.Asset + dbAsset.ConfigID = null.Int64FromPtr(config.Id).Int64 + dbAsset.ProjID = projId + dbAsset.DeviceID = deviceId + dbAsset.AssetID = assetId + return dbAsset.Insert(ctx, db.Database(), boil.Infer()) } -func SetConfigActive(appId int, state bool) { - err := db.Exec(db.Pool(), "update hailo.config set active = $1 where app_id = $2", state, appId) - if err != nil { - log.Error("Hailo", "Error during setting configuration inactive: %v", err) - } +func SetConfigActiveState(ctx context.Context, config apiserver.Configuration, state bool) (int64, error) { + return dbhailo.Configs( + dbhailo.ConfigWhere.AppID.EQ(null.Int64FromPtr(config.Id).Int64), + ).UpdateAll(ctx, db.Database(), dbhailo.M{ + dbhailo.ConfigColumns.Active: state, + }) } -func SetAllConfigsInactive() { - err := db.Exec(db.Pool(), "update hailo.config set active = false") - if err != nil { - log.Error("Hailo", "Error during setting configuration inactive: %v", err) +func ProjIds(config apiserver.Configuration) []string { + if config.ProjIds == nil { + return []string{} } + return *config.ProjIds +} + +func IsConfigActive(config apiserver.Configuration) bool { + return config.Active == nil || *config.Active +} + +func IsConfigEnabled(config apiserver.Configuration) bool { + return config.Enable == nil || *config.Enable +} + +func SetAllConfigsInactive(ctx context.Context) (int64, error) { + return dbhailo.Configs().UpdateAll(ctx, db.Database(), dbhailo.M{ + dbhailo.ConfigColumns.Active: false, + }) } diff --git a/conf/init.go b/conf/init.go index 672d64f..854d499 100644 --- a/conf/init.go +++ b/conf/init.go @@ -16,33 +16,24 @@ package conf import ( + "context" + "github.com/eliona-smart-building-assistant/go-utils/common" "github.com/eliona-smart-building-assistant/go-utils/db" - "github.com/eliona-smart-building-assistant/go-utils/log" + "hailo/apiserver" ) // InitConfiguration creates a default configuration to demonstrate how the eliona app should be configured. This configuration // points to a not existing endpoint and have to be changed. func InitConfiguration(connection db.Connection) error { - err := db.Exec(connection, "insert into hailo.config ("+ - "config, "+ - "enable, "+ - "description, "+ - "interval_sec, "+ - "inactive_timeout)"+ - " values ($1, $2, $3, $4, $5) on conflict do nothing", - FdsConfig{ - Name: "username", - Password: "password", - AuthServer: "https://foo.execute-api.eu-central-1.amazonaws.com", - FdsServer: "https://bar.execute-api.eu-central-1.amazonaws.com/hailo/v1", - }, - true, - "Hailo FDS demo configuration. Please change to your hailo server endpoints and authentication.", - 60, // 1 minute - 12*60*60, // 12 hours - ) - if err != nil { - log.Error("Hailo", "Error during init hailo config with a demo configuration: %v", err) - } + _, err := InsertConfig(context.Background(), apiserver.Configuration{ + Enable: common.Ptr(true), + Description: common.Ptr("Hailo FDS demo configuration. Please change to your hailo server endpoints and authentication."), + IntervalSec: 60, // 1 minute + InactiveTimeout: 12 * 60 * 60, // 12 hours + Username: common.Ptr("username"), + Password: common.Ptr("password"), + AuthServer: common.Ptr("https://foo.execute-api.eu-central-1.amazonaws.com"), + FdsServer: common.Ptr("https://bar.execute-api.eu-central-1.amazonaws.com/hailo/v1"), + }) return err } diff --git a/conf/init.sql b/conf/init.sql index e2fd59b..fee805c 100644 --- a/conf/init.sql +++ b/conf/init.sql @@ -31,3 +31,6 @@ create table if not exists hailo.config active boolean default false, proj_ids text[] ); + +-- Makes the new objects available for all other init steps +commit; \ No newline at end of file diff --git a/conf/v2.0.0.sql b/conf/v2.0.0.sql index 1a43c0f..0bf14e1 100644 --- a/conf/v2.0.0.sql +++ b/conf/v2.0.0.sql @@ -31,3 +31,6 @@ create table if not exists hailo.asset asset_id integer not null, primary key (config_id, device_id, proj_id, asset_id) ); + +-- Makes the new objects available for all other init steps +commit; \ No newline at end of file diff --git a/db/hailo/asset.go b/db/hailo/asset.go new file mode 100644 index 0000000..36e0361 --- /dev/null +++ b/db/hailo/asset.go @@ -0,0 +1,1063 @@ +// Code generated by SQLBoiler 4.13.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbhailo + +import ( + "context" + "database/sql" + "fmt" + "reflect" + "strconv" + "strings" + "sync" + "time" + + "github.com/friendsofgo/errors" + "github.com/volatiletech/sqlboiler/v4/boil" + "github.com/volatiletech/sqlboiler/v4/queries" + "github.com/volatiletech/sqlboiler/v4/queries/qm" + "github.com/volatiletech/sqlboiler/v4/queries/qmhelper" + "github.com/volatiletech/strmangle" +) + +// Asset is an object representing the database table. +type Asset struct { + ConfigID int64 `boil:"config_id" json:"config_id" toml:"config_id" yaml:"config_id"` + DeviceID string `boil:"device_id" json:"device_id" toml:"device_id" yaml:"device_id"` + ProjID string `boil:"proj_id" json:"proj_id" toml:"proj_id" yaml:"proj_id"` + AssetID int32 `boil:"asset_id" json:"asset_id" toml:"asset_id" yaml:"asset_id"` + + R *assetR `boil:"-" json:"-" toml:"-" yaml:"-"` + L assetL `boil:"-" json:"-" toml:"-" yaml:"-"` +} + +var AssetColumns = struct { + ConfigID string + DeviceID string + ProjID string + AssetID string +}{ + ConfigID: "config_id", + DeviceID: "device_id", + ProjID: "proj_id", + AssetID: "asset_id", +} + +var AssetTableColumns = struct { + ConfigID string + DeviceID string + ProjID string + AssetID string +}{ + ConfigID: "asset.config_id", + DeviceID: "asset.device_id", + ProjID: "asset.proj_id", + AssetID: "asset.asset_id", +} + +// Generated where + +type whereHelperint64 struct{ field string } + +func (w whereHelperint64) EQ(x int64) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.EQ, x) } +func (w whereHelperint64) NEQ(x int64) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.NEQ, x) } +func (w whereHelperint64) LT(x int64) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LT, x) } +func (w whereHelperint64) LTE(x int64) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LTE, x) } +func (w whereHelperint64) GT(x int64) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GT, x) } +func (w whereHelperint64) GTE(x int64) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GTE, x) } +func (w whereHelperint64) IN(slice []int64) qm.QueryMod { + values := make([]interface{}, 0, len(slice)) + for _, value := range slice { + values = append(values, value) + } + return qm.WhereIn(fmt.Sprintf("%s IN ?", w.field), values...) +} +func (w whereHelperint64) NIN(slice []int64) qm.QueryMod { + values := make([]interface{}, 0, len(slice)) + for _, value := range slice { + values = append(values, value) + } + return qm.WhereNotIn(fmt.Sprintf("%s NOT IN ?", w.field), values...) +} + +type whereHelperstring struct{ field string } + +func (w whereHelperstring) EQ(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.EQ, x) } +func (w whereHelperstring) NEQ(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.NEQ, x) } +func (w whereHelperstring) LT(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LT, x) } +func (w whereHelperstring) LTE(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LTE, x) } +func (w whereHelperstring) GT(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GT, x) } +func (w whereHelperstring) GTE(x string) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GTE, x) } +func (w whereHelperstring) IN(slice []string) qm.QueryMod { + values := make([]interface{}, 0, len(slice)) + for _, value := range slice { + values = append(values, value) + } + return qm.WhereIn(fmt.Sprintf("%s IN ?", w.field), values...) +} +func (w whereHelperstring) NIN(slice []string) qm.QueryMod { + values := make([]interface{}, 0, len(slice)) + for _, value := range slice { + values = append(values, value) + } + return qm.WhereNotIn(fmt.Sprintf("%s NOT IN ?", w.field), values...) +} + +type whereHelperint32 struct{ field string } + +func (w whereHelperint32) EQ(x int32) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.EQ, x) } +func (w whereHelperint32) NEQ(x int32) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.NEQ, x) } +func (w whereHelperint32) LT(x int32) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LT, x) } +func (w whereHelperint32) LTE(x int32) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LTE, x) } +func (w whereHelperint32) GT(x int32) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GT, x) } +func (w whereHelperint32) GTE(x int32) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GTE, x) } +func (w whereHelperint32) IN(slice []int32) qm.QueryMod { + values := make([]interface{}, 0, len(slice)) + for _, value := range slice { + values = append(values, value) + } + return qm.WhereIn(fmt.Sprintf("%s IN ?", w.field), values...) +} +func (w whereHelperint32) NIN(slice []int32) qm.QueryMod { + values := make([]interface{}, 0, len(slice)) + for _, value := range slice { + values = append(values, value) + } + return qm.WhereNotIn(fmt.Sprintf("%s NOT IN ?", w.field), values...) +} + +var AssetWhere = struct { + ConfigID whereHelperint64 + DeviceID whereHelperstring + ProjID whereHelperstring + AssetID whereHelperint32 +}{ + ConfigID: whereHelperint64{field: "\"hailo\".\"asset\".\"config_id\""}, + DeviceID: whereHelperstring{field: "\"hailo\".\"asset\".\"device_id\""}, + ProjID: whereHelperstring{field: "\"hailo\".\"asset\".\"proj_id\""}, + AssetID: whereHelperint32{field: "\"hailo\".\"asset\".\"asset_id\""}, +} + +// AssetRels is where relationship names are stored. +var AssetRels = struct { +}{} + +// assetR is where relationships are stored. +type assetR struct { +} + +// NewStruct creates a new relationship struct +func (*assetR) NewStruct() *assetR { + return &assetR{} +} + +// assetL is where Load methods for each relationship are stored. +type assetL struct{} + +var ( + assetAllColumns = []string{"config_id", "device_id", "proj_id", "asset_id"} + assetColumnsWithoutDefault = []string{"config_id", "device_id", "proj_id", "asset_id"} + assetColumnsWithDefault = []string{} + assetPrimaryKeyColumns = []string{"config_id", "device_id", "proj_id", "asset_id"} + assetGeneratedColumns = []string{} +) + +type ( + // AssetSlice is an alias for a slice of pointers to Asset. + // This should almost always be used instead of []Asset. + AssetSlice []*Asset + // AssetHook is the signature for custom Asset hook methods + AssetHook func(context.Context, boil.ContextExecutor, *Asset) error + + assetQuery struct { + *queries.Query + } +) + +// Cache for insert, update and upsert +var ( + assetType = reflect.TypeOf(&Asset{}) + assetMapping = queries.MakeStructMapping(assetType) + assetPrimaryKeyMapping, _ = queries.BindMapping(assetType, assetMapping, assetPrimaryKeyColumns) + assetInsertCacheMut sync.RWMutex + assetInsertCache = make(map[string]insertCache) + assetUpdateCacheMut sync.RWMutex + assetUpdateCache = make(map[string]updateCache) + assetUpsertCacheMut sync.RWMutex + assetUpsertCache = make(map[string]insertCache) +) + +var ( + // Force time package dependency for automated UpdatedAt/CreatedAt. + _ = time.Second + // Force qmhelper dependency for where clause generation (which doesn't + // always happen) + _ = qmhelper.Where +) + +var assetAfterSelectHooks []AssetHook + +var assetBeforeInsertHooks []AssetHook +var assetAfterInsertHooks []AssetHook + +var assetBeforeUpdateHooks []AssetHook +var assetAfterUpdateHooks []AssetHook + +var assetBeforeDeleteHooks []AssetHook +var assetAfterDeleteHooks []AssetHook + +var assetBeforeUpsertHooks []AssetHook +var assetAfterUpsertHooks []AssetHook + +// doAfterSelectHooks executes all "after Select" hooks. +func (o *Asset) doAfterSelectHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range assetAfterSelectHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doBeforeInsertHooks executes all "before insert" hooks. +func (o *Asset) doBeforeInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range assetBeforeInsertHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doAfterInsertHooks executes all "after Insert" hooks. +func (o *Asset) doAfterInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range assetAfterInsertHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doBeforeUpdateHooks executes all "before Update" hooks. +func (o *Asset) doBeforeUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range assetBeforeUpdateHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doAfterUpdateHooks executes all "after Update" hooks. +func (o *Asset) doAfterUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range assetAfterUpdateHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doBeforeDeleteHooks executes all "before Delete" hooks. +func (o *Asset) doBeforeDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range assetBeforeDeleteHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doAfterDeleteHooks executes all "after Delete" hooks. +func (o *Asset) doAfterDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range assetAfterDeleteHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doBeforeUpsertHooks executes all "before Upsert" hooks. +func (o *Asset) doBeforeUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range assetBeforeUpsertHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doAfterUpsertHooks executes all "after Upsert" hooks. +func (o *Asset) doAfterUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range assetAfterUpsertHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// AddAssetHook registers your hook function for all future operations. +func AddAssetHook(hookPoint boil.HookPoint, assetHook AssetHook) { + switch hookPoint { + case boil.AfterSelectHook: + assetAfterSelectHooks = append(assetAfterSelectHooks, assetHook) + case boil.BeforeInsertHook: + assetBeforeInsertHooks = append(assetBeforeInsertHooks, assetHook) + case boil.AfterInsertHook: + assetAfterInsertHooks = append(assetAfterInsertHooks, assetHook) + case boil.BeforeUpdateHook: + assetBeforeUpdateHooks = append(assetBeforeUpdateHooks, assetHook) + case boil.AfterUpdateHook: + assetAfterUpdateHooks = append(assetAfterUpdateHooks, assetHook) + case boil.BeforeDeleteHook: + assetBeforeDeleteHooks = append(assetBeforeDeleteHooks, assetHook) + case boil.AfterDeleteHook: + assetAfterDeleteHooks = append(assetAfterDeleteHooks, assetHook) + case boil.BeforeUpsertHook: + assetBeforeUpsertHooks = append(assetBeforeUpsertHooks, assetHook) + case boil.AfterUpsertHook: + assetAfterUpsertHooks = append(assetAfterUpsertHooks, assetHook) + } +} + +// OneG returns a single asset record from the query using the global executor. +func (q assetQuery) OneG(ctx context.Context) (*Asset, error) { + return q.One(ctx, boil.GetContextDB()) +} + +// One returns a single asset record from the query. +func (q assetQuery) One(ctx context.Context, exec boil.ContextExecutor) (*Asset, error) { + o := &Asset{} + + queries.SetLimit(q.Query, 1) + + err := q.Bind(ctx, exec, o) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, sql.ErrNoRows + } + return nil, errors.Wrap(err, "dbhailo: failed to execute a one query for asset") + } + + if err := o.doAfterSelectHooks(ctx, exec); err != nil { + return o, err + } + + return o, nil +} + +// AllG returns all Asset records from the query using the global executor. +func (q assetQuery) AllG(ctx context.Context) (AssetSlice, error) { + return q.All(ctx, boil.GetContextDB()) +} + +// All returns all Asset records from the query. +func (q assetQuery) All(ctx context.Context, exec boil.ContextExecutor) (AssetSlice, error) { + var o []*Asset + + err := q.Bind(ctx, exec, &o) + if err != nil { + return nil, errors.Wrap(err, "dbhailo: failed to assign all query results to Asset slice") + } + + if len(assetAfterSelectHooks) != 0 { + for _, obj := range o { + if err := obj.doAfterSelectHooks(ctx, exec); err != nil { + return o, err + } + } + } + + return o, nil +} + +// CountG returns the count of all Asset records in the query using the global executor +func (q assetQuery) CountG(ctx context.Context) (int64, error) { + return q.Count(ctx, boil.GetContextDB()) +} + +// Count returns the count of all Asset records in the query. +func (q assetQuery) Count(ctx context.Context, exec boil.ContextExecutor) (int64, error) { + var count int64 + + queries.SetSelect(q.Query, nil) + queries.SetCount(q.Query) + + err := q.Query.QueryRowContext(ctx, exec).Scan(&count) + if err != nil { + return 0, errors.Wrap(err, "dbhailo: failed to count asset rows") + } + + return count, nil +} + +// ExistsG checks if the row exists in the table using the global executor. +func (q assetQuery) ExistsG(ctx context.Context) (bool, error) { + return q.Exists(ctx, boil.GetContextDB()) +} + +// Exists checks if the row exists in the table. +func (q assetQuery) Exists(ctx context.Context, exec boil.ContextExecutor) (bool, error) { + var count int64 + + queries.SetSelect(q.Query, nil) + queries.SetCount(q.Query) + queries.SetLimit(q.Query, 1) + + err := q.Query.QueryRowContext(ctx, exec).Scan(&count) + if err != nil { + return false, errors.Wrap(err, "dbhailo: failed to check if asset exists") + } + + return count > 0, nil +} + +// Assets retrieves all the records using an executor. +func Assets(mods ...qm.QueryMod) assetQuery { + mods = append(mods, qm.From("\"hailo\".\"asset\"")) + q := NewQuery(mods...) + if len(queries.GetSelect(q)) == 0 { + queries.SetSelect(q, []string{"\"hailo\".\"asset\".*"}) + } + + return assetQuery{q} +} + +// FindAssetG retrieves a single record by ID. +func FindAssetG(ctx context.Context, configID int64, deviceID string, projID string, assetID int32, selectCols ...string) (*Asset, error) { + return FindAsset(ctx, boil.GetContextDB(), configID, deviceID, projID, assetID, selectCols...) +} + +// FindAsset retrieves a single record by ID with an executor. +// If selectCols is empty Find will return all columns. +func FindAsset(ctx context.Context, exec boil.ContextExecutor, configID int64, deviceID string, projID string, assetID int32, selectCols ...string) (*Asset, error) { + assetObj := &Asset{} + + sel := "*" + if len(selectCols) > 0 { + sel = strings.Join(strmangle.IdentQuoteSlice(dialect.LQ, dialect.RQ, selectCols), ",") + } + query := fmt.Sprintf( + "select %s from \"hailo\".\"asset\" where \"config_id\"=$1 AND \"device_id\"=$2 AND \"proj_id\"=$3 AND \"asset_id\"=$4", sel, + ) + + q := queries.Raw(query, configID, deviceID, projID, assetID) + + err := q.Bind(ctx, exec, assetObj) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, sql.ErrNoRows + } + return nil, errors.Wrap(err, "dbhailo: unable to select from asset") + } + + if err = assetObj.doAfterSelectHooks(ctx, exec); err != nil { + return assetObj, err + } + + return assetObj, nil +} + +// InsertG a single record. See Insert for whitelist behavior description. +func (o *Asset) InsertG(ctx context.Context, columns boil.Columns) error { + return o.Insert(ctx, boil.GetContextDB(), columns) +} + +// Insert a single record using an executor. +// See boil.Columns.InsertColumnSet documentation to understand column list inference for inserts. +func (o *Asset) Insert(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) error { + if o == nil { + return errors.New("dbhailo: no asset provided for insertion") + } + + var err error + + if err := o.doBeforeInsertHooks(ctx, exec); err != nil { + return err + } + + nzDefaults := queries.NonZeroDefaultSet(assetColumnsWithDefault, o) + + key := makeCacheKey(columns, nzDefaults) + assetInsertCacheMut.RLock() + cache, cached := assetInsertCache[key] + assetInsertCacheMut.RUnlock() + + if !cached { + wl, returnColumns := columns.InsertColumnSet( + assetAllColumns, + assetColumnsWithDefault, + assetColumnsWithoutDefault, + nzDefaults, + ) + + cache.valueMapping, err = queries.BindMapping(assetType, assetMapping, wl) + if err != nil { + return err + } + cache.retMapping, err = queries.BindMapping(assetType, assetMapping, returnColumns) + if err != nil { + return err + } + if len(wl) != 0 { + cache.query = fmt.Sprintf("INSERT INTO \"hailo\".\"asset\" (\"%s\") %%sVALUES (%s)%%s", strings.Join(wl, "\",\""), strmangle.Placeholders(dialect.UseIndexPlaceholders, len(wl), 1, 1)) + } else { + cache.query = "INSERT INTO \"hailo\".\"asset\" %sDEFAULT VALUES%s" + } + + var queryOutput, queryReturning string + + if len(cache.retMapping) != 0 { + queryReturning = fmt.Sprintf(" RETURNING \"%s\"", strings.Join(returnColumns, "\",\"")) + } + + cache.query = fmt.Sprintf(cache.query, queryOutput, queryReturning) + } + + value := reflect.Indirect(reflect.ValueOf(o)) + vals := queries.ValuesFromMapping(value, cache.valueMapping) + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, cache.query) + fmt.Fprintln(writer, vals) + } + + if len(cache.retMapping) != 0 { + err = exec.QueryRowContext(ctx, cache.query, vals...).Scan(queries.PtrsFromMapping(value, cache.retMapping)...) + } else { + _, err = exec.ExecContext(ctx, cache.query, vals...) + } + + if err != nil { + return errors.Wrap(err, "dbhailo: unable to insert into asset") + } + + if !cached { + assetInsertCacheMut.Lock() + assetInsertCache[key] = cache + assetInsertCacheMut.Unlock() + } + + return o.doAfterInsertHooks(ctx, exec) +} + +// UpdateG a single Asset record using the global executor. +// See Update for more documentation. +func (o *Asset) UpdateG(ctx context.Context, columns boil.Columns) (int64, error) { + return o.Update(ctx, boil.GetContextDB(), columns) +} + +// Update uses an executor to update the Asset. +// See boil.Columns.UpdateColumnSet documentation to understand column list inference for updates. +// Update does not automatically update the record in case of default values. Use .Reload() to refresh the records. +func (o *Asset) Update(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) (int64, error) { + var err error + if err = o.doBeforeUpdateHooks(ctx, exec); err != nil { + return 0, err + } + key := makeCacheKey(columns, nil) + assetUpdateCacheMut.RLock() + cache, cached := assetUpdateCache[key] + assetUpdateCacheMut.RUnlock() + + if !cached { + wl := columns.UpdateColumnSet( + assetAllColumns, + assetPrimaryKeyColumns, + ) + + if !columns.IsWhitelist() { + wl = strmangle.SetComplement(wl, []string{"created_at"}) + } + if len(wl) == 0 { + return 0, errors.New("dbhailo: unable to update asset, could not build whitelist") + } + + cache.query = fmt.Sprintf("UPDATE \"hailo\".\"asset\" SET %s WHERE %s", + strmangle.SetParamNames("\"", "\"", 1, wl), + strmangle.WhereClause("\"", "\"", len(wl)+1, assetPrimaryKeyColumns), + ) + cache.valueMapping, err = queries.BindMapping(assetType, assetMapping, append(wl, assetPrimaryKeyColumns...)) + if err != nil { + return 0, err + } + } + + values := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), cache.valueMapping) + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, cache.query) + fmt.Fprintln(writer, values) + } + var result sql.Result + result, err = exec.ExecContext(ctx, cache.query, values...) + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to update asset row") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbhailo: failed to get rows affected by update for asset") + } + + if !cached { + assetUpdateCacheMut.Lock() + assetUpdateCache[key] = cache + assetUpdateCacheMut.Unlock() + } + + return rowsAff, o.doAfterUpdateHooks(ctx, exec) +} + +// UpdateAllG updates all rows with the specified column values. +func (q assetQuery) UpdateAllG(ctx context.Context, cols M) (int64, error) { + return q.UpdateAll(ctx, boil.GetContextDB(), cols) +} + +// UpdateAll updates all rows with the specified column values. +func (q assetQuery) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) { + queries.SetUpdate(q.Query, cols) + + result, err := q.Query.ExecContext(ctx, exec) + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to update all for asset") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to retrieve rows affected for asset") + } + + return rowsAff, nil +} + +// UpdateAllG updates all rows with the specified column values. +func (o AssetSlice) UpdateAllG(ctx context.Context, cols M) (int64, error) { + return o.UpdateAll(ctx, boil.GetContextDB(), cols) +} + +// UpdateAll updates all rows with the specified column values, using an executor. +func (o AssetSlice) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) { + ln := int64(len(o)) + if ln == 0 { + return 0, nil + } + + if len(cols) == 0 { + return 0, errors.New("dbhailo: update all requires at least one column argument") + } + + colNames := make([]string, len(cols)) + args := make([]interface{}, len(cols)) + + i := 0 + for name, value := range cols { + colNames[i] = name + args[i] = value + i++ + } + + // Append all of the primary key values for each column + for _, obj := range o { + pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), assetPrimaryKeyMapping) + args = append(args, pkeyArgs...) + } + + sql := fmt.Sprintf("UPDATE \"hailo\".\"asset\" SET %s WHERE %s", + strmangle.SetParamNames("\"", "\"", 1, colNames), + strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), len(colNames)+1, assetPrimaryKeyColumns, len(o))) + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, sql) + fmt.Fprintln(writer, args...) + } + result, err := exec.ExecContext(ctx, sql, args...) + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to update all in asset slice") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to retrieve rows affected all in update all asset") + } + return rowsAff, nil +} + +// UpsertG attempts an insert, and does an update or ignore on conflict. +func (o *Asset) UpsertG(ctx context.Context, updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns) error { + return o.Upsert(ctx, boil.GetContextDB(), updateOnConflict, conflictColumns, updateColumns, insertColumns) +} + +// Upsert attempts an insert using an executor, and does an update or ignore on conflict. +// See boil.Columns documentation for how to properly use updateColumns and insertColumns. +func (o *Asset) Upsert(ctx context.Context, exec boil.ContextExecutor, updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns) error { + if o == nil { + return errors.New("dbhailo: no asset provided for upsert") + } + + if err := o.doBeforeUpsertHooks(ctx, exec); err != nil { + return err + } + + nzDefaults := queries.NonZeroDefaultSet(assetColumnsWithDefault, o) + + // Build cache key in-line uglily - mysql vs psql problems + buf := strmangle.GetBuffer() + if updateOnConflict { + buf.WriteByte('t') + } else { + buf.WriteByte('f') + } + buf.WriteByte('.') + for _, c := range conflictColumns { + buf.WriteString(c) + } + buf.WriteByte('.') + buf.WriteString(strconv.Itoa(updateColumns.Kind)) + for _, c := range updateColumns.Cols { + buf.WriteString(c) + } + buf.WriteByte('.') + buf.WriteString(strconv.Itoa(insertColumns.Kind)) + for _, c := range insertColumns.Cols { + buf.WriteString(c) + } + buf.WriteByte('.') + for _, c := range nzDefaults { + buf.WriteString(c) + } + key := buf.String() + strmangle.PutBuffer(buf) + + assetUpsertCacheMut.RLock() + cache, cached := assetUpsertCache[key] + assetUpsertCacheMut.RUnlock() + + var err error + + if !cached { + insert, ret := insertColumns.InsertColumnSet( + assetAllColumns, + assetColumnsWithDefault, + assetColumnsWithoutDefault, + nzDefaults, + ) + + update := updateColumns.UpdateColumnSet( + assetAllColumns, + assetPrimaryKeyColumns, + ) + + if updateOnConflict && len(update) == 0 { + return errors.New("dbhailo: unable to upsert asset, could not build update column list") + } + + conflict := conflictColumns + if len(conflict) == 0 { + conflict = make([]string, len(assetPrimaryKeyColumns)) + copy(conflict, assetPrimaryKeyColumns) + } + cache.query = buildUpsertQueryPostgres(dialect, "\"hailo\".\"asset\"", updateOnConflict, ret, update, conflict, insert) + + cache.valueMapping, err = queries.BindMapping(assetType, assetMapping, insert) + if err != nil { + return err + } + if len(ret) != 0 { + cache.retMapping, err = queries.BindMapping(assetType, assetMapping, ret) + if err != nil { + return err + } + } + } + + value := reflect.Indirect(reflect.ValueOf(o)) + vals := queries.ValuesFromMapping(value, cache.valueMapping) + var returns []interface{} + if len(cache.retMapping) != 0 { + returns = queries.PtrsFromMapping(value, cache.retMapping) + } + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, cache.query) + fmt.Fprintln(writer, vals) + } + if len(cache.retMapping) != 0 { + err = exec.QueryRowContext(ctx, cache.query, vals...).Scan(returns...) + if errors.Is(err, sql.ErrNoRows) { + err = nil // Postgres doesn't return anything when there's no update + } + } else { + _, err = exec.ExecContext(ctx, cache.query, vals...) + } + if err != nil { + return errors.Wrap(err, "dbhailo: unable to upsert asset") + } + + if !cached { + assetUpsertCacheMut.Lock() + assetUpsertCache[key] = cache + assetUpsertCacheMut.Unlock() + } + + return o.doAfterUpsertHooks(ctx, exec) +} + +// DeleteG deletes a single Asset record. +// DeleteG will match against the primary key column to find the record to delete. +func (o *Asset) DeleteG(ctx context.Context) (int64, error) { + return o.Delete(ctx, boil.GetContextDB()) +} + +// Delete deletes a single Asset record with an executor. +// Delete will match against the primary key column to find the record to delete. +func (o *Asset) Delete(ctx context.Context, exec boil.ContextExecutor) (int64, error) { + if o == nil { + return 0, errors.New("dbhailo: no Asset provided for delete") + } + + if err := o.doBeforeDeleteHooks(ctx, exec); err != nil { + return 0, err + } + + args := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), assetPrimaryKeyMapping) + sql := "DELETE FROM \"hailo\".\"asset\" WHERE \"config_id\"=$1 AND \"device_id\"=$2 AND \"proj_id\"=$3 AND \"asset_id\"=$4" + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, sql) + fmt.Fprintln(writer, args...) + } + result, err := exec.ExecContext(ctx, sql, args...) + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to delete from asset") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbhailo: failed to get rows affected by delete for asset") + } + + if err := o.doAfterDeleteHooks(ctx, exec); err != nil { + return 0, err + } + + return rowsAff, nil +} + +func (q assetQuery) DeleteAllG(ctx context.Context) (int64, error) { + return q.DeleteAll(ctx, boil.GetContextDB()) +} + +// DeleteAll deletes all matching rows. +func (q assetQuery) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) { + if q.Query == nil { + return 0, errors.New("dbhailo: no assetQuery provided for delete all") + } + + queries.SetDelete(q.Query) + + result, err := q.Query.ExecContext(ctx, exec) + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to delete all from asset") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbhailo: failed to get rows affected by deleteall for asset") + } + + return rowsAff, nil +} + +// DeleteAllG deletes all rows in the slice. +func (o AssetSlice) DeleteAllG(ctx context.Context) (int64, error) { + return o.DeleteAll(ctx, boil.GetContextDB()) +} + +// DeleteAll deletes all rows in the slice, using an executor. +func (o AssetSlice) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) { + if len(o) == 0 { + return 0, nil + } + + if len(assetBeforeDeleteHooks) != 0 { + for _, obj := range o { + if err := obj.doBeforeDeleteHooks(ctx, exec); err != nil { + return 0, err + } + } + } + + var args []interface{} + for _, obj := range o { + pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), assetPrimaryKeyMapping) + args = append(args, pkeyArgs...) + } + + sql := "DELETE FROM \"hailo\".\"asset\" WHERE " + + strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 1, assetPrimaryKeyColumns, len(o)) + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, sql) + fmt.Fprintln(writer, args) + } + result, err := exec.ExecContext(ctx, sql, args...) + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to delete all from asset slice") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbhailo: failed to get rows affected by deleteall for asset") + } + + if len(assetAfterDeleteHooks) != 0 { + for _, obj := range o { + if err := obj.doAfterDeleteHooks(ctx, exec); err != nil { + return 0, err + } + } + } + + return rowsAff, nil +} + +// ReloadG refetches the object from the database using the primary keys. +func (o *Asset) ReloadG(ctx context.Context) error { + if o == nil { + return errors.New("dbhailo: no Asset provided for reload") + } + + return o.Reload(ctx, boil.GetContextDB()) +} + +// Reload refetches the object from the database +// using the primary keys with an executor. +func (o *Asset) Reload(ctx context.Context, exec boil.ContextExecutor) error { + ret, err := FindAsset(ctx, exec, o.ConfigID, o.DeviceID, o.ProjID, o.AssetID) + if err != nil { + return err + } + + *o = *ret + return nil +} + +// ReloadAllG refetches every row with matching primary key column values +// and overwrites the original object slice with the newly updated slice. +func (o *AssetSlice) ReloadAllG(ctx context.Context) error { + if o == nil { + return errors.New("dbhailo: empty AssetSlice provided for reload all") + } + + return o.ReloadAll(ctx, boil.GetContextDB()) +} + +// ReloadAll refetches every row with matching primary key column values +// and overwrites the original object slice with the newly updated slice. +func (o *AssetSlice) ReloadAll(ctx context.Context, exec boil.ContextExecutor) error { + if o == nil || len(*o) == 0 { + return nil + } + + slice := AssetSlice{} + var args []interface{} + for _, obj := range *o { + pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), assetPrimaryKeyMapping) + args = append(args, pkeyArgs...) + } + + sql := "SELECT \"hailo\".\"asset\".* FROM \"hailo\".\"asset\" WHERE " + + strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 1, assetPrimaryKeyColumns, len(*o)) + + q := queries.Raw(sql, args...) + + err := q.Bind(ctx, exec, &slice) + if err != nil { + return errors.Wrap(err, "dbhailo: unable to reload all in AssetSlice") + } + + *o = slice + + return nil +} + +// AssetExistsG checks if the Asset row exists. +func AssetExistsG(ctx context.Context, configID int64, deviceID string, projID string, assetID int32) (bool, error) { + return AssetExists(ctx, boil.GetContextDB(), configID, deviceID, projID, assetID) +} + +// AssetExists checks if the Asset row exists. +func AssetExists(ctx context.Context, exec boil.ContextExecutor, configID int64, deviceID string, projID string, assetID int32) (bool, error) { + var exists bool + sql := "select exists(select 1 from \"hailo\".\"asset\" where \"config_id\"=$1 AND \"device_id\"=$2 AND \"proj_id\"=$3 AND \"asset_id\"=$4 limit 1)" + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, sql) + fmt.Fprintln(writer, configID, deviceID, projID, assetID) + } + row := exec.QueryRowContext(ctx, sql, configID, deviceID, projID, assetID) + + err := row.Scan(&exists) + if err != nil { + return false, errors.Wrap(err, "dbhailo: unable to check if asset exists") + } + + return exists, nil +} diff --git a/db/hailo/boil_queries.go b/db/hailo/boil_queries.go new file mode 100644 index 0000000..3123574 --- /dev/null +++ b/db/hailo/boil_queries.go @@ -0,0 +1,33 @@ +// Code generated by SQLBoiler 4.13.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbhailo + +import ( + "github.com/volatiletech/sqlboiler/v4/drivers" + "github.com/volatiletech/sqlboiler/v4/queries" + "github.com/volatiletech/sqlboiler/v4/queries/qm" +) + +var dialect = drivers.Dialect{ + LQ: 0x22, + RQ: 0x22, + + UseIndexPlaceholders: true, + UseLastInsertID: false, + UseSchema: true, + UseDefaultKeyword: true, + UseAutoColumns: false, + UseTopClause: false, + UseOutputClause: false, + UseCaseWhenExistsClause: false, +} + +// NewQuery initializes a new Query using the passed in QueryMods +func NewQuery(mods ...qm.QueryMod) *queries.Query { + q := &queries.Query{} + queries.SetDialect(q, &dialect) + qm.Apply(q, mods...) + + return q +} diff --git a/db/hailo/boil_table_names.go b/db/hailo/boil_table_names.go new file mode 100644 index 0000000..dd8ce87 --- /dev/null +++ b/db/hailo/boil_table_names.go @@ -0,0 +1,12 @@ +// Code generated by SQLBoiler 4.13.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbhailo + +var TableNames = struct { + Asset string + Config string +}{ + Asset: "asset", + Config: "config", +} diff --git a/db/hailo/boil_types.go b/db/hailo/boil_types.go new file mode 100644 index 0000000..856bfc4 --- /dev/null +++ b/db/hailo/boil_types.go @@ -0,0 +1,52 @@ +// Code generated by SQLBoiler 4.13.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbhailo + +import ( + "strconv" + + "github.com/friendsofgo/errors" + "github.com/volatiletech/sqlboiler/v4/boil" + "github.com/volatiletech/strmangle" +) + +// M type is for providing columns and column values to UpdateAll. +type M map[string]interface{} + +// ErrSyncFail occurs during insert when the record could not be retrieved in +// order to populate default value information. This usually happens when LastInsertId +// fails or there was a primary key configuration that was not resolvable. +var ErrSyncFail = errors.New("dbhailo: failed to synchronize data after insert") + +type insertCache struct { + query string + retQuery string + valueMapping []uint64 + retMapping []uint64 +} + +type updateCache struct { + query string + valueMapping []uint64 +} + +func makeCacheKey(cols boil.Columns, nzDefaults []string) string { + buf := strmangle.GetBuffer() + + buf.WriteString(strconv.Itoa(cols.Kind)) + for _, w := range cols.Cols { + buf.WriteString(w) + } + + if len(nzDefaults) != 0 { + buf.WriteByte('.') + } + for _, nz := range nzDefaults { + buf.WriteString(nz) + } + + str := buf.String() + strmangle.PutBuffer(buf) + return str +} diff --git a/db/hailo/boil_view_names.go b/db/hailo/boil_view_names.go new file mode 100644 index 0000000..5ba4587 --- /dev/null +++ b/db/hailo/boil_view_names.go @@ -0,0 +1,7 @@ +// Code generated by SQLBoiler 4.13.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbhailo + +var ViewNames = struct { +}{} diff --git a/db/hailo/config.go b/db/hailo/config.go new file mode 100644 index 0000000..2382344 --- /dev/null +++ b/db/hailo/config.go @@ -0,0 +1,1192 @@ +// Code generated by SQLBoiler 4.13.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbhailo + +import ( + "context" + "database/sql" + "fmt" + "reflect" + "strconv" + "strings" + "sync" + "time" + + "github.com/friendsofgo/errors" + "github.com/volatiletech/null/v8" + "github.com/volatiletech/sqlboiler/v4/boil" + "github.com/volatiletech/sqlboiler/v4/queries" + "github.com/volatiletech/sqlboiler/v4/queries/qm" + "github.com/volatiletech/sqlboiler/v4/queries/qmhelper" + "github.com/volatiletech/sqlboiler/v4/types" + "github.com/volatiletech/strmangle" +) + +// Config is an object representing the database table. +type Config struct { + AppID int64 `boil:"app_id" json:"app_id" toml:"app_id" yaml:"app_id"` + Config types.JSON `boil:"config" json:"config" toml:"config" yaml:"config"` + Enable null.Bool `boil:"enable" json:"enable,omitempty" toml:"enable" yaml:"enable,omitempty"` + Description null.String `boil:"description" json:"description,omitempty" toml:"description" yaml:"description,omitempty"` + AssetID null.Int32 `boil:"asset_id" json:"asset_id,omitempty" toml:"asset_id" yaml:"asset_id,omitempty"` + IntervalSec int32 `boil:"interval_sec" json:"interval_sec" toml:"interval_sec" yaml:"interval_sec"` + AuthTimeout int32 `boil:"auth_timeout" json:"auth_timeout" toml:"auth_timeout" yaml:"auth_timeout"` + RequestTimeout int32 `boil:"request_timeout" json:"request_timeout" toml:"request_timeout" yaml:"request_timeout"` + InactiveTimeout null.Int32 `boil:"inactive_timeout" json:"inactive_timeout,omitempty" toml:"inactive_timeout" yaml:"inactive_timeout,omitempty"` + Active null.Bool `boil:"active" json:"active,omitempty" toml:"active" yaml:"active,omitempty"` + ProjIds types.StringArray `boil:"proj_ids" json:"proj_ids,omitempty" toml:"proj_ids" yaml:"proj_ids,omitempty"` + + R *configR `boil:"-" json:"-" toml:"-" yaml:"-"` + L configL `boil:"-" json:"-" toml:"-" yaml:"-"` +} + +var ConfigColumns = struct { + AppID string + Config string + Enable string + Description string + AssetID string + IntervalSec string + AuthTimeout string + RequestTimeout string + InactiveTimeout string + Active string + ProjIds string +}{ + AppID: "app_id", + Config: "config", + Enable: "enable", + Description: "description", + AssetID: "asset_id", + IntervalSec: "interval_sec", + AuthTimeout: "auth_timeout", + RequestTimeout: "request_timeout", + InactiveTimeout: "inactive_timeout", + Active: "active", + ProjIds: "proj_ids", +} + +var ConfigTableColumns = struct { + AppID string + Config string + Enable string + Description string + AssetID string + IntervalSec string + AuthTimeout string + RequestTimeout string + InactiveTimeout string + Active string + ProjIds string +}{ + AppID: "config.app_id", + Config: "config.config", + Enable: "config.enable", + Description: "config.description", + AssetID: "config.asset_id", + IntervalSec: "config.interval_sec", + AuthTimeout: "config.auth_timeout", + RequestTimeout: "config.request_timeout", + InactiveTimeout: "config.inactive_timeout", + Active: "config.active", + ProjIds: "config.proj_ids", +} + +// Generated where + +type whereHelpertypes_JSON struct{ field string } + +func (w whereHelpertypes_JSON) EQ(x types.JSON) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.EQ, x) +} +func (w whereHelpertypes_JSON) NEQ(x types.JSON) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.NEQ, x) +} +func (w whereHelpertypes_JSON) LT(x types.JSON) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.LT, x) +} +func (w whereHelpertypes_JSON) LTE(x types.JSON) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.LTE, x) +} +func (w whereHelpertypes_JSON) GT(x types.JSON) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.GT, x) +} +func (w whereHelpertypes_JSON) GTE(x types.JSON) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.GTE, x) +} + +type whereHelpernull_Bool struct{ field string } + +func (w whereHelpernull_Bool) EQ(x null.Bool) qm.QueryMod { + return qmhelper.WhereNullEQ(w.field, false, x) +} +func (w whereHelpernull_Bool) NEQ(x null.Bool) qm.QueryMod { + return qmhelper.WhereNullEQ(w.field, true, x) +} +func (w whereHelpernull_Bool) LT(x null.Bool) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.LT, x) +} +func (w whereHelpernull_Bool) LTE(x null.Bool) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.LTE, x) +} +func (w whereHelpernull_Bool) GT(x null.Bool) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.GT, x) +} +func (w whereHelpernull_Bool) GTE(x null.Bool) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.GTE, x) +} + +func (w whereHelpernull_Bool) IsNull() qm.QueryMod { return qmhelper.WhereIsNull(w.field) } +func (w whereHelpernull_Bool) IsNotNull() qm.QueryMod { return qmhelper.WhereIsNotNull(w.field) } + +type whereHelpernull_String struct{ field string } + +func (w whereHelpernull_String) EQ(x null.String) qm.QueryMod { + return qmhelper.WhereNullEQ(w.field, false, x) +} +func (w whereHelpernull_String) NEQ(x null.String) qm.QueryMod { + return qmhelper.WhereNullEQ(w.field, true, x) +} +func (w whereHelpernull_String) LT(x null.String) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.LT, x) +} +func (w whereHelpernull_String) LTE(x null.String) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.LTE, x) +} +func (w whereHelpernull_String) GT(x null.String) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.GT, x) +} +func (w whereHelpernull_String) GTE(x null.String) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.GTE, x) +} +func (w whereHelpernull_String) IN(slice []string) qm.QueryMod { + values := make([]interface{}, 0, len(slice)) + for _, value := range slice { + values = append(values, value) + } + return qm.WhereIn(fmt.Sprintf("%s IN ?", w.field), values...) +} +func (w whereHelpernull_String) NIN(slice []string) qm.QueryMod { + values := make([]interface{}, 0, len(slice)) + for _, value := range slice { + values = append(values, value) + } + return qm.WhereNotIn(fmt.Sprintf("%s NOT IN ?", w.field), values...) +} + +func (w whereHelpernull_String) IsNull() qm.QueryMod { return qmhelper.WhereIsNull(w.field) } +func (w whereHelpernull_String) IsNotNull() qm.QueryMod { return qmhelper.WhereIsNotNull(w.field) } + +type whereHelpernull_Int32 struct{ field string } + +func (w whereHelpernull_Int32) EQ(x null.Int32) qm.QueryMod { + return qmhelper.WhereNullEQ(w.field, false, x) +} +func (w whereHelpernull_Int32) NEQ(x null.Int32) qm.QueryMod { + return qmhelper.WhereNullEQ(w.field, true, x) +} +func (w whereHelpernull_Int32) LT(x null.Int32) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.LT, x) +} +func (w whereHelpernull_Int32) LTE(x null.Int32) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.LTE, x) +} +func (w whereHelpernull_Int32) GT(x null.Int32) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.GT, x) +} +func (w whereHelpernull_Int32) GTE(x null.Int32) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.GTE, x) +} +func (w whereHelpernull_Int32) IN(slice []int32) qm.QueryMod { + values := make([]interface{}, 0, len(slice)) + for _, value := range slice { + values = append(values, value) + } + return qm.WhereIn(fmt.Sprintf("%s IN ?", w.field), values...) +} +func (w whereHelpernull_Int32) NIN(slice []int32) qm.QueryMod { + values := make([]interface{}, 0, len(slice)) + for _, value := range slice { + values = append(values, value) + } + return qm.WhereNotIn(fmt.Sprintf("%s NOT IN ?", w.field), values...) +} + +func (w whereHelpernull_Int32) IsNull() qm.QueryMod { return qmhelper.WhereIsNull(w.field) } +func (w whereHelpernull_Int32) IsNotNull() qm.QueryMod { return qmhelper.WhereIsNotNull(w.field) } + +type whereHelpertypes_StringArray struct{ field string } + +func (w whereHelpertypes_StringArray) EQ(x types.StringArray) qm.QueryMod { + return qmhelper.WhereNullEQ(w.field, false, x) +} +func (w whereHelpertypes_StringArray) NEQ(x types.StringArray) qm.QueryMod { + return qmhelper.WhereNullEQ(w.field, true, x) +} +func (w whereHelpertypes_StringArray) LT(x types.StringArray) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.LT, x) +} +func (w whereHelpertypes_StringArray) LTE(x types.StringArray) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.LTE, x) +} +func (w whereHelpertypes_StringArray) GT(x types.StringArray) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.GT, x) +} +func (w whereHelpertypes_StringArray) GTE(x types.StringArray) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.GTE, x) +} + +func (w whereHelpertypes_StringArray) IsNull() qm.QueryMod { return qmhelper.WhereIsNull(w.field) } +func (w whereHelpertypes_StringArray) IsNotNull() qm.QueryMod { + return qmhelper.WhereIsNotNull(w.field) +} + +var ConfigWhere = struct { + AppID whereHelperint64 + Config whereHelpertypes_JSON + Enable whereHelpernull_Bool + Description whereHelpernull_String + AssetID whereHelpernull_Int32 + IntervalSec whereHelperint32 + AuthTimeout whereHelperint32 + RequestTimeout whereHelperint32 + InactiveTimeout whereHelpernull_Int32 + Active whereHelpernull_Bool + ProjIds whereHelpertypes_StringArray +}{ + AppID: whereHelperint64{field: "\"hailo\".\"config\".\"app_id\""}, + Config: whereHelpertypes_JSON{field: "\"hailo\".\"config\".\"config\""}, + Enable: whereHelpernull_Bool{field: "\"hailo\".\"config\".\"enable\""}, + Description: whereHelpernull_String{field: "\"hailo\".\"config\".\"description\""}, + AssetID: whereHelpernull_Int32{field: "\"hailo\".\"config\".\"asset_id\""}, + IntervalSec: whereHelperint32{field: "\"hailo\".\"config\".\"interval_sec\""}, + AuthTimeout: whereHelperint32{field: "\"hailo\".\"config\".\"auth_timeout\""}, + RequestTimeout: whereHelperint32{field: "\"hailo\".\"config\".\"request_timeout\""}, + InactiveTimeout: whereHelpernull_Int32{field: "\"hailo\".\"config\".\"inactive_timeout\""}, + Active: whereHelpernull_Bool{field: "\"hailo\".\"config\".\"active\""}, + ProjIds: whereHelpertypes_StringArray{field: "\"hailo\".\"config\".\"proj_ids\""}, +} + +// ConfigRels is where relationship names are stored. +var ConfigRels = struct { +}{} + +// configR is where relationships are stored. +type configR struct { +} + +// NewStruct creates a new relationship struct +func (*configR) NewStruct() *configR { + return &configR{} +} + +// configL is where Load methods for each relationship are stored. +type configL struct{} + +var ( + configAllColumns = []string{"app_id", "config", "enable", "description", "asset_id", "interval_sec", "auth_timeout", "request_timeout", "inactive_timeout", "active", "proj_ids"} + configColumnsWithoutDefault = []string{"config", "interval_sec"} + configColumnsWithDefault = []string{"app_id", "enable", "description", "asset_id", "auth_timeout", "request_timeout", "inactive_timeout", "active", "proj_ids"} + configPrimaryKeyColumns = []string{"app_id"} + configGeneratedColumns = []string{} +) + +type ( + // ConfigSlice is an alias for a slice of pointers to Config. + // This should almost always be used instead of []Config. + ConfigSlice []*Config + // ConfigHook is the signature for custom Config hook methods + ConfigHook func(context.Context, boil.ContextExecutor, *Config) error + + configQuery struct { + *queries.Query + } +) + +// Cache for insert, update and upsert +var ( + configType = reflect.TypeOf(&Config{}) + configMapping = queries.MakeStructMapping(configType) + configPrimaryKeyMapping, _ = queries.BindMapping(configType, configMapping, configPrimaryKeyColumns) + configInsertCacheMut sync.RWMutex + configInsertCache = make(map[string]insertCache) + configUpdateCacheMut sync.RWMutex + configUpdateCache = make(map[string]updateCache) + configUpsertCacheMut sync.RWMutex + configUpsertCache = make(map[string]insertCache) +) + +var ( + // Force time package dependency for automated UpdatedAt/CreatedAt. + _ = time.Second + // Force qmhelper dependency for where clause generation (which doesn't + // always happen) + _ = qmhelper.Where +) + +var configAfterSelectHooks []ConfigHook + +var configBeforeInsertHooks []ConfigHook +var configAfterInsertHooks []ConfigHook + +var configBeforeUpdateHooks []ConfigHook +var configAfterUpdateHooks []ConfigHook + +var configBeforeDeleteHooks []ConfigHook +var configAfterDeleteHooks []ConfigHook + +var configBeforeUpsertHooks []ConfigHook +var configAfterUpsertHooks []ConfigHook + +// doAfterSelectHooks executes all "after Select" hooks. +func (o *Config) doAfterSelectHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range configAfterSelectHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doBeforeInsertHooks executes all "before insert" hooks. +func (o *Config) doBeforeInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range configBeforeInsertHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doAfterInsertHooks executes all "after Insert" hooks. +func (o *Config) doAfterInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range configAfterInsertHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doBeforeUpdateHooks executes all "before Update" hooks. +func (o *Config) doBeforeUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range configBeforeUpdateHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doAfterUpdateHooks executes all "after Update" hooks. +func (o *Config) doAfterUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range configAfterUpdateHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doBeforeDeleteHooks executes all "before Delete" hooks. +func (o *Config) doBeforeDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range configBeforeDeleteHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doAfterDeleteHooks executes all "after Delete" hooks. +func (o *Config) doAfterDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range configAfterDeleteHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doBeforeUpsertHooks executes all "before Upsert" hooks. +func (o *Config) doBeforeUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range configBeforeUpsertHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// doAfterUpsertHooks executes all "after Upsert" hooks. +func (o *Config) doAfterUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) { + if boil.HooksAreSkipped(ctx) { + return nil + } + + for _, hook := range configAfterUpsertHooks { + if err := hook(ctx, exec, o); err != nil { + return err + } + } + + return nil +} + +// AddConfigHook registers your hook function for all future operations. +func AddConfigHook(hookPoint boil.HookPoint, configHook ConfigHook) { + switch hookPoint { + case boil.AfterSelectHook: + configAfterSelectHooks = append(configAfterSelectHooks, configHook) + case boil.BeforeInsertHook: + configBeforeInsertHooks = append(configBeforeInsertHooks, configHook) + case boil.AfterInsertHook: + configAfterInsertHooks = append(configAfterInsertHooks, configHook) + case boil.BeforeUpdateHook: + configBeforeUpdateHooks = append(configBeforeUpdateHooks, configHook) + case boil.AfterUpdateHook: + configAfterUpdateHooks = append(configAfterUpdateHooks, configHook) + case boil.BeforeDeleteHook: + configBeforeDeleteHooks = append(configBeforeDeleteHooks, configHook) + case boil.AfterDeleteHook: + configAfterDeleteHooks = append(configAfterDeleteHooks, configHook) + case boil.BeforeUpsertHook: + configBeforeUpsertHooks = append(configBeforeUpsertHooks, configHook) + case boil.AfterUpsertHook: + configAfterUpsertHooks = append(configAfterUpsertHooks, configHook) + } +} + +// OneG returns a single config record from the query using the global executor. +func (q configQuery) OneG(ctx context.Context) (*Config, error) { + return q.One(ctx, boil.GetContextDB()) +} + +// One returns a single config record from the query. +func (q configQuery) One(ctx context.Context, exec boil.ContextExecutor) (*Config, error) { + o := &Config{} + + queries.SetLimit(q.Query, 1) + + err := q.Bind(ctx, exec, o) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, sql.ErrNoRows + } + return nil, errors.Wrap(err, "dbhailo: failed to execute a one query for config") + } + + if err := o.doAfterSelectHooks(ctx, exec); err != nil { + return o, err + } + + return o, nil +} + +// AllG returns all Config records from the query using the global executor. +func (q configQuery) AllG(ctx context.Context) (ConfigSlice, error) { + return q.All(ctx, boil.GetContextDB()) +} + +// All returns all Config records from the query. +func (q configQuery) All(ctx context.Context, exec boil.ContextExecutor) (ConfigSlice, error) { + var o []*Config + + err := q.Bind(ctx, exec, &o) + if err != nil { + return nil, errors.Wrap(err, "dbhailo: failed to assign all query results to Config slice") + } + + if len(configAfterSelectHooks) != 0 { + for _, obj := range o { + if err := obj.doAfterSelectHooks(ctx, exec); err != nil { + return o, err + } + } + } + + return o, nil +} + +// CountG returns the count of all Config records in the query using the global executor +func (q configQuery) CountG(ctx context.Context) (int64, error) { + return q.Count(ctx, boil.GetContextDB()) +} + +// Count returns the count of all Config records in the query. +func (q configQuery) Count(ctx context.Context, exec boil.ContextExecutor) (int64, error) { + var count int64 + + queries.SetSelect(q.Query, nil) + queries.SetCount(q.Query) + + err := q.Query.QueryRowContext(ctx, exec).Scan(&count) + if err != nil { + return 0, errors.Wrap(err, "dbhailo: failed to count config rows") + } + + return count, nil +} + +// ExistsG checks if the row exists in the table using the global executor. +func (q configQuery) ExistsG(ctx context.Context) (bool, error) { + return q.Exists(ctx, boil.GetContextDB()) +} + +// Exists checks if the row exists in the table. +func (q configQuery) Exists(ctx context.Context, exec boil.ContextExecutor) (bool, error) { + var count int64 + + queries.SetSelect(q.Query, nil) + queries.SetCount(q.Query) + queries.SetLimit(q.Query, 1) + + err := q.Query.QueryRowContext(ctx, exec).Scan(&count) + if err != nil { + return false, errors.Wrap(err, "dbhailo: failed to check if config exists") + } + + return count > 0, nil +} + +// Configs retrieves all the records using an executor. +func Configs(mods ...qm.QueryMod) configQuery { + mods = append(mods, qm.From("\"hailo\".\"config\"")) + q := NewQuery(mods...) + if len(queries.GetSelect(q)) == 0 { + queries.SetSelect(q, []string{"\"hailo\".\"config\".*"}) + } + + return configQuery{q} +} + +// FindConfigG retrieves a single record by ID. +func FindConfigG(ctx context.Context, appID int64, selectCols ...string) (*Config, error) { + return FindConfig(ctx, boil.GetContextDB(), appID, selectCols...) +} + +// FindConfig retrieves a single record by ID with an executor. +// If selectCols is empty Find will return all columns. +func FindConfig(ctx context.Context, exec boil.ContextExecutor, appID int64, selectCols ...string) (*Config, error) { + configObj := &Config{} + + sel := "*" + if len(selectCols) > 0 { + sel = strings.Join(strmangle.IdentQuoteSlice(dialect.LQ, dialect.RQ, selectCols), ",") + } + query := fmt.Sprintf( + "select %s from \"hailo\".\"config\" where \"app_id\"=$1", sel, + ) + + q := queries.Raw(query, appID) + + err := q.Bind(ctx, exec, configObj) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, sql.ErrNoRows + } + return nil, errors.Wrap(err, "dbhailo: unable to select from config") + } + + if err = configObj.doAfterSelectHooks(ctx, exec); err != nil { + return configObj, err + } + + return configObj, nil +} + +// InsertG a single record. See Insert for whitelist behavior description. +func (o *Config) InsertG(ctx context.Context, columns boil.Columns) error { + return o.Insert(ctx, boil.GetContextDB(), columns) +} + +// Insert a single record using an executor. +// See boil.Columns.InsertColumnSet documentation to understand column list inference for inserts. +func (o *Config) Insert(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) error { + if o == nil { + return errors.New("dbhailo: no config provided for insertion") + } + + var err error + + if err := o.doBeforeInsertHooks(ctx, exec); err != nil { + return err + } + + nzDefaults := queries.NonZeroDefaultSet(configColumnsWithDefault, o) + + key := makeCacheKey(columns, nzDefaults) + configInsertCacheMut.RLock() + cache, cached := configInsertCache[key] + configInsertCacheMut.RUnlock() + + if !cached { + wl, returnColumns := columns.InsertColumnSet( + configAllColumns, + configColumnsWithDefault, + configColumnsWithoutDefault, + nzDefaults, + ) + + cache.valueMapping, err = queries.BindMapping(configType, configMapping, wl) + if err != nil { + return err + } + cache.retMapping, err = queries.BindMapping(configType, configMapping, returnColumns) + if err != nil { + return err + } + if len(wl) != 0 { + cache.query = fmt.Sprintf("INSERT INTO \"hailo\".\"config\" (\"%s\") %%sVALUES (%s)%%s", strings.Join(wl, "\",\""), strmangle.Placeholders(dialect.UseIndexPlaceholders, len(wl), 1, 1)) + } else { + cache.query = "INSERT INTO \"hailo\".\"config\" %sDEFAULT VALUES%s" + } + + var queryOutput, queryReturning string + + if len(cache.retMapping) != 0 { + queryReturning = fmt.Sprintf(" RETURNING \"%s\"", strings.Join(returnColumns, "\",\"")) + } + + cache.query = fmt.Sprintf(cache.query, queryOutput, queryReturning) + } + + value := reflect.Indirect(reflect.ValueOf(o)) + vals := queries.ValuesFromMapping(value, cache.valueMapping) + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, cache.query) + fmt.Fprintln(writer, vals) + } + + if len(cache.retMapping) != 0 { + err = exec.QueryRowContext(ctx, cache.query, vals...).Scan(queries.PtrsFromMapping(value, cache.retMapping)...) + } else { + _, err = exec.ExecContext(ctx, cache.query, vals...) + } + + if err != nil { + return errors.Wrap(err, "dbhailo: unable to insert into config") + } + + if !cached { + configInsertCacheMut.Lock() + configInsertCache[key] = cache + configInsertCacheMut.Unlock() + } + + return o.doAfterInsertHooks(ctx, exec) +} + +// UpdateG a single Config record using the global executor. +// See Update for more documentation. +func (o *Config) UpdateG(ctx context.Context, columns boil.Columns) (int64, error) { + return o.Update(ctx, boil.GetContextDB(), columns) +} + +// Update uses an executor to update the Config. +// See boil.Columns.UpdateColumnSet documentation to understand column list inference for updates. +// Update does not automatically update the record in case of default values. Use .Reload() to refresh the records. +func (o *Config) Update(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) (int64, error) { + var err error + if err = o.doBeforeUpdateHooks(ctx, exec); err != nil { + return 0, err + } + key := makeCacheKey(columns, nil) + configUpdateCacheMut.RLock() + cache, cached := configUpdateCache[key] + configUpdateCacheMut.RUnlock() + + if !cached { + wl := columns.UpdateColumnSet( + configAllColumns, + configPrimaryKeyColumns, + ) + + if !columns.IsWhitelist() { + wl = strmangle.SetComplement(wl, []string{"created_at"}) + } + if len(wl) == 0 { + return 0, errors.New("dbhailo: unable to update config, could not build whitelist") + } + + cache.query = fmt.Sprintf("UPDATE \"hailo\".\"config\" SET %s WHERE %s", + strmangle.SetParamNames("\"", "\"", 1, wl), + strmangle.WhereClause("\"", "\"", len(wl)+1, configPrimaryKeyColumns), + ) + cache.valueMapping, err = queries.BindMapping(configType, configMapping, append(wl, configPrimaryKeyColumns...)) + if err != nil { + return 0, err + } + } + + values := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), cache.valueMapping) + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, cache.query) + fmt.Fprintln(writer, values) + } + var result sql.Result + result, err = exec.ExecContext(ctx, cache.query, values...) + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to update config row") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbhailo: failed to get rows affected by update for config") + } + + if !cached { + configUpdateCacheMut.Lock() + configUpdateCache[key] = cache + configUpdateCacheMut.Unlock() + } + + return rowsAff, o.doAfterUpdateHooks(ctx, exec) +} + +// UpdateAllG updates all rows with the specified column values. +func (q configQuery) UpdateAllG(ctx context.Context, cols M) (int64, error) { + return q.UpdateAll(ctx, boil.GetContextDB(), cols) +} + +// UpdateAll updates all rows with the specified column values. +func (q configQuery) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) { + queries.SetUpdate(q.Query, cols) + + result, err := q.Query.ExecContext(ctx, exec) + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to update all for config") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to retrieve rows affected for config") + } + + return rowsAff, nil +} + +// UpdateAllG updates all rows with the specified column values. +func (o ConfigSlice) UpdateAllG(ctx context.Context, cols M) (int64, error) { + return o.UpdateAll(ctx, boil.GetContextDB(), cols) +} + +// UpdateAll updates all rows with the specified column values, using an executor. +func (o ConfigSlice) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) { + ln := int64(len(o)) + if ln == 0 { + return 0, nil + } + + if len(cols) == 0 { + return 0, errors.New("dbhailo: update all requires at least one column argument") + } + + colNames := make([]string, len(cols)) + args := make([]interface{}, len(cols)) + + i := 0 + for name, value := range cols { + colNames[i] = name + args[i] = value + i++ + } + + // Append all of the primary key values for each column + for _, obj := range o { + pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), configPrimaryKeyMapping) + args = append(args, pkeyArgs...) + } + + sql := fmt.Sprintf("UPDATE \"hailo\".\"config\" SET %s WHERE %s", + strmangle.SetParamNames("\"", "\"", 1, colNames), + strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), len(colNames)+1, configPrimaryKeyColumns, len(o))) + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, sql) + fmt.Fprintln(writer, args...) + } + result, err := exec.ExecContext(ctx, sql, args...) + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to update all in config slice") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to retrieve rows affected all in update all config") + } + return rowsAff, nil +} + +// UpsertG attempts an insert, and does an update or ignore on conflict. +func (o *Config) UpsertG(ctx context.Context, updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns) error { + return o.Upsert(ctx, boil.GetContextDB(), updateOnConflict, conflictColumns, updateColumns, insertColumns) +} + +// Upsert attempts an insert using an executor, and does an update or ignore on conflict. +// See boil.Columns documentation for how to properly use updateColumns and insertColumns. +func (o *Config) Upsert(ctx context.Context, exec boil.ContextExecutor, updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns) error { + if o == nil { + return errors.New("dbhailo: no config provided for upsert") + } + + if err := o.doBeforeUpsertHooks(ctx, exec); err != nil { + return err + } + + nzDefaults := queries.NonZeroDefaultSet(configColumnsWithDefault, o) + + // Build cache key in-line uglily - mysql vs psql problems + buf := strmangle.GetBuffer() + if updateOnConflict { + buf.WriteByte('t') + } else { + buf.WriteByte('f') + } + buf.WriteByte('.') + for _, c := range conflictColumns { + buf.WriteString(c) + } + buf.WriteByte('.') + buf.WriteString(strconv.Itoa(updateColumns.Kind)) + for _, c := range updateColumns.Cols { + buf.WriteString(c) + } + buf.WriteByte('.') + buf.WriteString(strconv.Itoa(insertColumns.Kind)) + for _, c := range insertColumns.Cols { + buf.WriteString(c) + } + buf.WriteByte('.') + for _, c := range nzDefaults { + buf.WriteString(c) + } + key := buf.String() + strmangle.PutBuffer(buf) + + configUpsertCacheMut.RLock() + cache, cached := configUpsertCache[key] + configUpsertCacheMut.RUnlock() + + var err error + + if !cached { + insert, ret := insertColumns.InsertColumnSet( + configAllColumns, + configColumnsWithDefault, + configColumnsWithoutDefault, + nzDefaults, + ) + + update := updateColumns.UpdateColumnSet( + configAllColumns, + configPrimaryKeyColumns, + ) + + if updateOnConflict && len(update) == 0 { + return errors.New("dbhailo: unable to upsert config, could not build update column list") + } + + conflict := conflictColumns + if len(conflict) == 0 { + conflict = make([]string, len(configPrimaryKeyColumns)) + copy(conflict, configPrimaryKeyColumns) + } + cache.query = buildUpsertQueryPostgres(dialect, "\"hailo\".\"config\"", updateOnConflict, ret, update, conflict, insert) + + cache.valueMapping, err = queries.BindMapping(configType, configMapping, insert) + if err != nil { + return err + } + if len(ret) != 0 { + cache.retMapping, err = queries.BindMapping(configType, configMapping, ret) + if err != nil { + return err + } + } + } + + value := reflect.Indirect(reflect.ValueOf(o)) + vals := queries.ValuesFromMapping(value, cache.valueMapping) + var returns []interface{} + if len(cache.retMapping) != 0 { + returns = queries.PtrsFromMapping(value, cache.retMapping) + } + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, cache.query) + fmt.Fprintln(writer, vals) + } + if len(cache.retMapping) != 0 { + err = exec.QueryRowContext(ctx, cache.query, vals...).Scan(returns...) + if errors.Is(err, sql.ErrNoRows) { + err = nil // Postgres doesn't return anything when there's no update + } + } else { + _, err = exec.ExecContext(ctx, cache.query, vals...) + } + if err != nil { + return errors.Wrap(err, "dbhailo: unable to upsert config") + } + + if !cached { + configUpsertCacheMut.Lock() + configUpsertCache[key] = cache + configUpsertCacheMut.Unlock() + } + + return o.doAfterUpsertHooks(ctx, exec) +} + +// DeleteG deletes a single Config record. +// DeleteG will match against the primary key column to find the record to delete. +func (o *Config) DeleteG(ctx context.Context) (int64, error) { + return o.Delete(ctx, boil.GetContextDB()) +} + +// Delete deletes a single Config record with an executor. +// Delete will match against the primary key column to find the record to delete. +func (o *Config) Delete(ctx context.Context, exec boil.ContextExecutor) (int64, error) { + if o == nil { + return 0, errors.New("dbhailo: no Config provided for delete") + } + + if err := o.doBeforeDeleteHooks(ctx, exec); err != nil { + return 0, err + } + + args := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), configPrimaryKeyMapping) + sql := "DELETE FROM \"hailo\".\"config\" WHERE \"app_id\"=$1" + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, sql) + fmt.Fprintln(writer, args...) + } + result, err := exec.ExecContext(ctx, sql, args...) + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to delete from config") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbhailo: failed to get rows affected by delete for config") + } + + if err := o.doAfterDeleteHooks(ctx, exec); err != nil { + return 0, err + } + + return rowsAff, nil +} + +func (q configQuery) DeleteAllG(ctx context.Context) (int64, error) { + return q.DeleteAll(ctx, boil.GetContextDB()) +} + +// DeleteAll deletes all matching rows. +func (q configQuery) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) { + if q.Query == nil { + return 0, errors.New("dbhailo: no configQuery provided for delete all") + } + + queries.SetDelete(q.Query) + + result, err := q.Query.ExecContext(ctx, exec) + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to delete all from config") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbhailo: failed to get rows affected by deleteall for config") + } + + return rowsAff, nil +} + +// DeleteAllG deletes all rows in the slice. +func (o ConfigSlice) DeleteAllG(ctx context.Context) (int64, error) { + return o.DeleteAll(ctx, boil.GetContextDB()) +} + +// DeleteAll deletes all rows in the slice, using an executor. +func (o ConfigSlice) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) { + if len(o) == 0 { + return 0, nil + } + + if len(configBeforeDeleteHooks) != 0 { + for _, obj := range o { + if err := obj.doBeforeDeleteHooks(ctx, exec); err != nil { + return 0, err + } + } + } + + var args []interface{} + for _, obj := range o { + pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), configPrimaryKeyMapping) + args = append(args, pkeyArgs...) + } + + sql := "DELETE FROM \"hailo\".\"config\" WHERE " + + strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 1, configPrimaryKeyColumns, len(o)) + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, sql) + fmt.Fprintln(writer, args) + } + result, err := exec.ExecContext(ctx, sql, args...) + if err != nil { + return 0, errors.Wrap(err, "dbhailo: unable to delete all from config slice") + } + + rowsAff, err := result.RowsAffected() + if err != nil { + return 0, errors.Wrap(err, "dbhailo: failed to get rows affected by deleteall for config") + } + + if len(configAfterDeleteHooks) != 0 { + for _, obj := range o { + if err := obj.doAfterDeleteHooks(ctx, exec); err != nil { + return 0, err + } + } + } + + return rowsAff, nil +} + +// ReloadG refetches the object from the database using the primary keys. +func (o *Config) ReloadG(ctx context.Context) error { + if o == nil { + return errors.New("dbhailo: no Config provided for reload") + } + + return o.Reload(ctx, boil.GetContextDB()) +} + +// Reload refetches the object from the database +// using the primary keys with an executor. +func (o *Config) Reload(ctx context.Context, exec boil.ContextExecutor) error { + ret, err := FindConfig(ctx, exec, o.AppID) + if err != nil { + return err + } + + *o = *ret + return nil +} + +// ReloadAllG refetches every row with matching primary key column values +// and overwrites the original object slice with the newly updated slice. +func (o *ConfigSlice) ReloadAllG(ctx context.Context) error { + if o == nil { + return errors.New("dbhailo: empty ConfigSlice provided for reload all") + } + + return o.ReloadAll(ctx, boil.GetContextDB()) +} + +// ReloadAll refetches every row with matching primary key column values +// and overwrites the original object slice with the newly updated slice. +func (o *ConfigSlice) ReloadAll(ctx context.Context, exec boil.ContextExecutor) error { + if o == nil || len(*o) == 0 { + return nil + } + + slice := ConfigSlice{} + var args []interface{} + for _, obj := range *o { + pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), configPrimaryKeyMapping) + args = append(args, pkeyArgs...) + } + + sql := "SELECT \"hailo\".\"config\".* FROM \"hailo\".\"config\" WHERE " + + strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 1, configPrimaryKeyColumns, len(*o)) + + q := queries.Raw(sql, args...) + + err := q.Bind(ctx, exec, &slice) + if err != nil { + return errors.Wrap(err, "dbhailo: unable to reload all in ConfigSlice") + } + + *o = slice + + return nil +} + +// ConfigExistsG checks if the Config row exists. +func ConfigExistsG(ctx context.Context, appID int64) (bool, error) { + return ConfigExists(ctx, boil.GetContextDB(), appID) +} + +// ConfigExists checks if the Config row exists. +func ConfigExists(ctx context.Context, exec boil.ContextExecutor, appID int64) (bool, error) { + var exists bool + sql := "select exists(select 1 from \"hailo\".\"config\" where \"app_id\"=$1 limit 1)" + + if boil.IsDebug(ctx) { + writer := boil.DebugWriterFrom(ctx) + fmt.Fprintln(writer, sql) + fmt.Fprintln(writer, appID) + } + row := exec.QueryRowContext(ctx, sql, appID) + + err := row.Scan(&exists) + if err != nil { + return false, errors.Wrap(err, "dbhailo: unable to check if config exists") + } + + return exists, nil +} diff --git a/db/hailo/psql_upsert.go b/db/hailo/psql_upsert.go new file mode 100644 index 0000000..2617ef8 --- /dev/null +++ b/db/hailo/psql_upsert.go @@ -0,0 +1,61 @@ +// Code generated by SQLBoiler 4.13.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. + +package dbhailo + +import ( + "fmt" + "strings" + + "github.com/volatiletech/sqlboiler/v4/drivers" + "github.com/volatiletech/strmangle" +) + +// buildUpsertQueryPostgres builds a SQL statement string using the upsertData provided. +func buildUpsertQueryPostgres(dia drivers.Dialect, tableName string, updateOnConflict bool, ret, update, conflict, whitelist []string) string { + conflict = strmangle.IdentQuoteSlice(dia.LQ, dia.RQ, conflict) + whitelist = strmangle.IdentQuoteSlice(dia.LQ, dia.RQ, whitelist) + ret = strmangle.IdentQuoteSlice(dia.LQ, dia.RQ, ret) + + buf := strmangle.GetBuffer() + defer strmangle.PutBuffer(buf) + + columns := "DEFAULT VALUES" + if len(whitelist) != 0 { + columns = fmt.Sprintf("(%s) VALUES (%s)", + strings.Join(whitelist, ", "), + strmangle.Placeholders(dia.UseIndexPlaceholders, len(whitelist), 1, 1)) + } + + fmt.Fprintf( + buf, + "INSERT INTO %s %s ON CONFLICT ", + tableName, + columns, + ) + + if !updateOnConflict || len(update) == 0 { + buf.WriteString("DO NOTHING") + } else { + buf.WriteByte('(') + buf.WriteString(strings.Join(conflict, ", ")) + buf.WriteString(") DO UPDATE SET ") + + for i, v := range update { + if i != 0 { + buf.WriteByte(',') + } + quoted := strmangle.IdentQuote(dia.LQ, dia.RQ, v) + buf.WriteString(quoted) + buf.WriteString(" = EXCLUDED.") + buf.WriteString(quoted) + } + } + + if len(ret) != 0 { + buf.WriteString(" RETURNING ") + buf.WriteString(strings.Join(ret, ", ")) + } + + return buf.String() +} diff --git a/eliona/assets.go b/eliona/assets.go index 8474e3a..9c1af94 100644 --- a/eliona/assets.go +++ b/eliona/assets.go @@ -16,11 +16,13 @@ package eliona import ( + "context" "fmt" api "github.com/eliona-smart-building-assistant/go-eliona-api-client" "github.com/eliona-smart-building-assistant/go-eliona/asset" "github.com/eliona-smart-building-assistant/go-utils/common" "github.com/eliona-smart-building-assistant/go-utils/log" + "hailo/apiserver" "hailo/conf" "hailo/hailo" ) @@ -32,9 +34,9 @@ const ( ) // CreateAssetsIfNecessary create all assets for specification including sub specification if not already exists -func CreateAssetsIfNecessary(config conf.Config, spec hailo.Spec) error { +func CreateAssetsIfNecessary(config apiserver.Configuration, spec hailo.Spec) error { - for _, projectId := range config.ProjectIds { + for _, projectId := range conf.ProjIds(config) { assetId, err := createAssetIfNecessary(config, projectId, nil, spec) if err != nil { log.Error("Hailo", "Could not create assets for device %s: %v", spec.DeviceId, err) @@ -53,10 +55,10 @@ func CreateAssetsIfNecessary(config conf.Config, spec hailo.Spec) error { } // createAssetIfNecessary create asset for specification if not already exists -func createAssetIfNecessary(config conf.Config, projectId string, parentAssetId *int32, spec hailo.Spec) (*int32, error) { +func createAssetIfNecessary(config apiserver.Configuration, projectId string, parentAssetId *int32, spec hailo.Spec) (*int32, error) { // Get known asset id from configuration - existingId := conf.GetAssetId(config.Id, projectId, spec.DeviceId) + existingId, err := conf.GetAssetId(context.Background(), config, projectId, spec.DeviceId) if existingId != nil { return existingId, nil } @@ -83,7 +85,7 @@ func createAssetIfNecessary(config conf.Config, projectId string, parentAssetId } // Remember the asset id for further usage - err = conf.InsertAsset(config.Id, projectId, spec.DeviceId, *newId) + err = conf.InsertAsset(context.Background(), config, projectId, spec.DeviceId, *newId) if err != nil { return newId, err } diff --git a/eliona/data.go b/eliona/data.go index 34e1477..ff7acc9 100644 --- a/eliona/data.go +++ b/eliona/data.go @@ -16,19 +16,21 @@ package eliona import ( + "context" api "github.com/eliona-smart-building-assistant/go-eliona-api-client" "github.com/eliona-smart-building-assistant/go-eliona/asset" "github.com/eliona-smart-building-assistant/go-utils/common" "github.com/eliona-smart-building-assistant/go-utils/log" + "hailo/apiserver" "hailo/conf" "hailo/hailo" "math" "time" ) -func UpsertDataForDevices(config conf.Config, spec hailo.Spec) error { +func UpsertDataForDevices(config apiserver.Configuration, spec hailo.Spec) error { - for _, projectId := range config.ProjectIds { + for _, projectId := range conf.ProjIds(config) { err := upsertDataForDevice(config, projectId, spec) if err != nil { @@ -65,12 +67,16 @@ func upsertData(subtype api.DataSubtype, time time.Time, assetId int32, payload return nil } -func upsertDataForDevice(config conf.Config, projectId string, spec hailo.Spec) error { +func upsertDataForDevice(config apiserver.Configuration, projectId string, spec hailo.Spec) error { log.Debug("Hailo", "Upsert data for device: config %d and device '%s'", config.Id, spec.DeviceId) + assetId, err := conf.GetAssetId(context.Background(), config, projectId, spec.DeviceId) + if err != nil { + return err + } return upsertData( api.SUBTYPE_INFO, parseTime(spec.Generic.RegistrationDate), - *conf.GetAssetId(config.Id, projectId, spec.DeviceId), + *assetId, deviceDataPayload{RegistrationDate: spec.Generic.RegistrationDate, Volume: binVolume(spec)}, ) } @@ -91,14 +97,18 @@ type stationDataPayload struct { Active bool `json:"active"` } -func UpsertDataForStation(config conf.Config, status hailo.Status) error { - for _, projectId := range config.ProjectIds { +func UpsertDataForStation(config apiserver.Configuration, status hailo.Status) error { + for _, projectId := range conf.ProjIds(config) { log.Debug("Hailo", "Upsert data for station: config %d and station '%s'", config.Id, status.DeviceId) lastContact := parseTimeToHours(status.Generic.LastContact) - err := upsertData( + assetId, err := conf.GetAssetId(context.Background(), config, projectId, status.DeviceId) + if err != nil { + return err + } + err = upsertData( api.SUBTYPE_INPUT, parseTime(status.Generic.LastContact), - int32(*conf.GetAssetId(config.Id, projectId, status.DeviceId)), + *assetId, stationDataPayload{ int(status.DeviceTypeSpecific.AverageBatteryLevel * 100), lastContact, @@ -115,7 +125,7 @@ func UpsertDataForStation(config conf.Config, status hailo.Status) error { return nil } -func CheckActivity(connection conf.Config, lastContact float64) bool { +func CheckActivity(connection apiserver.Configuration, lastContact float64) bool { return lastContact < (float64)(connection.InactiveTimeout/3600) } @@ -135,15 +145,18 @@ type statusDataPayload struct { ExpectedPercent int `json:"exp_percent"` } -func UpsertDataForBin(config conf.Config, status hailo.Status, diag hailo.Diag) error { - for _, projectId := range config.ProjectIds { +func UpsertDataForBin(config apiserver.Configuration, status hailo.Status, diag hailo.Diag) error { + for _, projectId := range conf.ProjIds(config) { log.Debug("Hailo", "Upsert data for bin: config %d and bin '%s'", config.Id, status.DeviceId) - lastContact := parseTimeToHours(status.Generic.LastContact) - err := upsertData( + assetId, err := conf.GetAssetId(context.Background(), config, projectId, status.DeviceId) + if err != nil { + return err + } + err = upsertData( api.SUBTYPE_INPUT, parseTime(status.Generic.LastContact), - int32(*conf.GetAssetId(config.Id, projectId, status.DeviceId)), + *assetId, binDataPayload{ int(status.DeviceTypeSpecific.BatteryLevel * 100), status.DeviceTypeSpecific.LastEmptyCount, @@ -160,11 +173,14 @@ func UpsertDataForBin(config conf.Config, status hailo.Status, diag hailo.Diag) log.Error("Hailo", "Could not upsert data for bin %s: %v", status.DeviceId, err) return err } - + assetId, err = conf.GetAssetId(context.Background(), config, projectId, status.DeviceId) + if err != nil { + return err + } err = upsertData( api.SUBTYPE_STATUS, parseTime(status.Generic.LastContact), - int32(*conf.GetAssetId(config.Id, projectId, status.DeviceId)), + *assetId, statusDataPayload{int(diag.DeviceTypeSpecific.ExpectedFillingLevel * 100)}, ) if err != nil { diff --git a/generate-db.cmd b/generate-db.cmd index 48d1fd2..30177ac 100644 --- a/generate-db.cmd +++ b/generate-db.cmd @@ -4,39 +4,6 @@ go install github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-psql@latest go get github.com/volatiletech/sqlboiler/v4 go get github.com/volatiletech/null/v8 -docker run --rm -d ^ - --name "eliona_database_sql_boiler_code_generation" ^ - -e "POSTGRES_PASSWORD=secret" ^ - -p "60001:5432" ^ - debezium/postgres:12 - -docker run --rm ^ - --name "eliona_database_init_sql_boiler_code_generation" ^ - -e "PGPORT=60001" ^ - -e "PGDATABASE=postgres" ^ - -e "PGHOST=host.docker.internal" ^ - -e "PGUSER=postgres" ^ - -e "PGPASSWORD=secret" ^ - eliona.azurecr.io/core/database:develop - -docker exec ^ - "eliona_database_sql_boiler_code_generation" ^ - psql -d "postgres://postgres:secret@localhost:5432/iot" -c "ALTER TABLE alarm drop CONSTRAINT alarm_asset_id_subtype_fkey;" - -docker exec ^ - "eliona_database_sql_boiler_code_generation" ^ - psql -d "postgres://postgres:secret@localhost:5432/iot" -c "DROP SCHEMA IF EXISTS api CASCADE;" - -docker exec ^ - "eliona_database_sql_boiler_code_generation" ^ - psql -d "postgres://postgres:secret@localhost:5432/iot" -c "ALTER TABLE public.pipeline DROP COLUMN cov, DROP COLUMN lpf, DROP COLUMN hws, DROP COLUMN ala;" - sqlboiler psql ^ - -c sqlboiler-public.toml ^ + -c sqlboiler.toml ^ --wipe --no-tests - -sqlboiler psql ^ - -c sqlboiler-versioning.toml ^ - --wipe --no-tests - -docker stop "eliona_database_sql_boiler_code_generation" \ No newline at end of file diff --git a/go.mod b/go.mod index 0a8d0bc..a1fd849 100644 --- a/go.mod +++ b/go.mod @@ -5,14 +5,20 @@ go 1.18 require ( github.com/eliona-smart-building-assistant/go-eliona v1.7.4 github.com/eliona-smart-building-assistant/go-eliona-api-client v1.2.3 - github.com/eliona-smart-building-assistant/go-utils v1.0.0 + github.com/eliona-smart-building-assistant/go-utils v1.0.6 + github.com/friendsofgo/errors v0.9.2 github.com/gorilla/mux v1.8.0 github.com/stretchr/testify v1.8.0 + github.com/volatiletech/null/v8 v8.1.2 + github.com/volatiletech/sqlboiler/v4 v4.13.0 + github.com/volatiletech/strmangle v0.0.4 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/golang/protobuf v1.5.0 // indirect + github.com/ericlagergren/decimal v0.0.0-20181231230500-73749d4874d5 // indirect + github.com/gofrs/uuid v4.0.0+incompatible // indirect + github.com/golang/protobuf v1.5.2 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgconn v1.12.1 // indirect github.com/jackc/pgio v1.0.0 // indirect @@ -22,12 +28,17 @@ require ( github.com/jackc/pgtype v1.11.0 // indirect github.com/jackc/pgx/v4 v4.16.1 // indirect github.com/jackc/puddle v1.2.2-0.20220404125616-4e959849469a // indirect + github.com/lib/pq v1.10.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b // indirect - golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect - golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558 // indirect + github.com/spf13/cast v1.4.1 // indirect + github.com/volatiletech/inflect v0.0.1 // indirect + github.com/volatiletech/randomize v0.0.1 // indirect + golang.org/x/crypto v0.0.0-20220214200702-86341886e292 // indirect + golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect + golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect golang.org/x/text v0.3.7 // indirect - google.golang.org/appengine v1.6.6 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.27.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index d80264e..c4e852c 100644 --- a/go.sum +++ b/go.sum @@ -13,6 +13,16 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -21,6 +31,8 @@ cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4g cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/firestore v1.6.0/go.mod h1:afJwI0vaXwAG54kI7A//lP/lSPDkQORQuMkv56TxEPU= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -31,41 +43,92 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.0/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.13.1/go.mod h1:+nVKciyKD2J9TyVcEQ82Bo9b+3F92PiQfHrIE/zqLqM= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.9.1/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= +github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DATA-DOG/go-sqlmock v1.4.1 h1:ThlnYciV1iM/V0OSF/dtkqWb6xo5qITT1TJBG1MRDJM= +github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apmckinlay/gsuneido v0.0.0-20180907175622-1f10244968e3/go.mod h1:hJnaqxrCRgMCTWtpNz9XUFkBCREiQdlcyK6YNmOfroM= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eliona-smart-building-assistant/go-eliona v1.7.4 h1:xb3uVqpbCQCzBmTmXoP4TzUYS7P2EsyEmeB4rg+Q45c= github.com/eliona-smart-building-assistant/go-eliona v1.7.4/go.mod h1:j9uA7ehl+5fzG5qO95LyEDOxXq9nHzpOG0ovhLyY5Ys= github.com/eliona-smart-building-assistant/go-eliona-api-client v1.2.3 h1:vk/+sNiQdMvo2AFP6Vo+9Ojk/p9d9Q/ntl/dKJ7o4K0= github.com/eliona-smart-building-assistant/go-eliona-api-client v1.2.3/go.mod h1:dpFgZ2FfZBX7Ev6YHdtsaPqR95d0SOnQ1jx91NE5fbs= -github.com/eliona-smart-building-assistant/go-utils v1.0.0 h1:p/2W+b3+691QiyhZv/OQ329TV68BuJSqTRa8T4loYUA= -github.com/eliona-smart-building-assistant/go-utils v1.0.0/go.mod h1:NLtmKWXtefx3mqI+CHZKF287bspveXb6V8kArPRudEA= +github.com/eliona-smart-building-assistant/go-utils v1.0.6 h1:gUv4QxsCquLYKKX7tUJtZ/5T8SKovWNuLm2j+oWR0+U= +github.com/eliona-smart-building-assistant/go-utils v1.0.6/go.mod h1:mDgXKlaqLWPdPu5QJVs7oxqRVqTKfgvmmqhMm1zFEyU= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ericlagergren/decimal v0.0.0-20181231230500-73749d4874d5 h1:HQGCJNlqt1dUs/BhtEKmqWd6LWS+DWYVxi9+Jo4r0jE= +github.com/ericlagergren/decimal v0.0.0-20181231230500-73749d4874d5/go.mod h1:1yj25TwtUlJ+pfOu9apAVaM1RWfZGg+aFpd4hPQZekQ= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/friendsofgo/errors v0.9.2 h1:X6NYxef4efCBdwI7BgS820zFaN7Cphrmb+Pljdzjtgk= +github.com/friendsofgo/errors v0.9.2/go.mod h1:yCvFW5AkDIL9qn7suHVLiI/gH228n7PC4Pn44IGoTOI= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -77,6 +140,8 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -90,8 +155,12 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -101,10 +170,17 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -112,14 +188,57 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= +github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -169,43 +288,108 @@ github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dv github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.2.2-0.20220404125616-4e959849469a h1:oH7y/b+q2BEerCnARr/HZc1NxOYbKSJor4MqQXlhh+s= github.com/jackc/puddle v1.2.2-0.20220404125616-4e959849469a/go.mod h1:ZQuO1Un86Xpe1ShKl08ERTzYhzWq+OvrvotbpeE3XO0= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.1-0.20191011153232-f91d3411e481/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/microsoft/go-mssqldb v0.15.0/go.mod h1:Wr+jfynAR4lYmHA093AL8njUw2T6ovxe2jjBQKxBIco= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pashagolub/pgxmock v1.6.0 h1:4zugVDde5sBKEsuDog0e7aqQRu/mGpxxQP4GMZ1F7Kk= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/crypt v0.1.0/go.mod h1:B/mN0msZuINBtQ1zZLEQcegFJJf9vnYIR88KRMEuODE= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= +github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= +github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -214,42 +398,71 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/volatiletech/inflect v0.0.1 h1:2a6FcMQyhmPZcLa+uet3VJ8gLn/9svWhJxJYwvE8KsU= +github.com/volatiletech/inflect v0.0.1/go.mod h1:IBti31tG6phkHitLlr5j7shC5SOo//x0AjDzaJU1PLA= +github.com/volatiletech/null/v8 v8.1.2 h1:kiTiX1PpwvuugKwfvUNX/SU/5A2KGZMXfGD0DUHdKEI= +github.com/volatiletech/null/v8 v8.1.2/go.mod h1:98DbwNoKEpRrYtGjWFctievIfm4n4MxG0A6EBUcoS5g= +github.com/volatiletech/randomize v0.0.1 h1:eE5yajattWqTB2/eN8df4dw+8jwAzBtbdo5sbWC4nMk= +github.com/volatiletech/randomize v0.0.1/go.mod h1:GN3U0QYqfZ9FOJ67bzax1cqZ5q2xuj2mXrXBjWaRTlY= +github.com/volatiletech/sqlboiler/v4 v4.13.0 h1:dwrs3AEEGWNrEWDnrI1GILxp85p1Qb0WuzArpVXAZgk= +github.com/volatiletech/sqlboiler/v4 v4.13.0/go.mod h1:QmJpWSj/s9xGSHFr2SN/MF371fLgeo10PZ9Tl8AUQNw= +github.com/volatiletech/strmangle v0.0.1/go.mod h1:F6RA6IkB5vq0yTG4GQ0UsbbRcl3ni9P76i+JrTBKFFg= +github.com/volatiletech/strmangle v0.0.4 h1:CxrEPhobZL/PCZOTDSH1aq7s4Kv76hQpRoTVVlUOim4= +github.com/volatiletech/strmangle v0.0.4/go.mod h1:ycDvbDkjDvhC0NUU8w3fWwl5JEMTV56vTKXzR3GeR+0= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b h1:QAqMVf3pSa6eeTsuklijukjXBlj7Es2QQplab+/RbQ4= -golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -272,6 +485,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -280,8 +495,13 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -293,6 +513,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -307,16 +528,39 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558 h1:D7nTwh4J0i+5mW4Zjzn5omvlr6YBcWywE6KOcatyNxY= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -325,8 +569,13 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -339,13 +588,18 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -357,16 +611,45 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -379,6 +662,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -388,10 +672,12 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -415,9 +701,23 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -441,13 +741,26 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -471,12 +784,35 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -489,6 +825,20 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -500,15 +850,26 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -518,6 +879,119 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.33.9/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.33.11/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.34.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.4/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.5/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.7/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.8/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.10/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.15/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.16/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.17/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.18/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.20/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.22/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60= +modernc.org/ccgo/v3 v3.10.0/go.mod h1:c0yBmkRFi7uW4J7fwx/JiijwOjeAeR2NoSaRVFPmjMw= +modernc.org/ccgo/v3 v3.11.0/go.mod h1:dGNposbDp9TOZ/1KBxghxtUp/bzErD0/0QW4hhSaBMI= +modernc.org/ccgo/v3 v3.11.1/go.mod h1:lWHxfsn13L3f7hgGsGlU28D9eUOf6y3ZYHKoPaKU0ag= +modernc.org/ccgo/v3 v3.11.3/go.mod h1:0oHunRBMBiXOKdaglfMlRPBALQqsfrCKXgw9okQ3GEw= +modernc.org/ccgo/v3 v3.12.4/go.mod h1:Bk+m6m2tsooJchP/Yk5ji56cClmN6R1cqc9o/YtbgBQ= +modernc.org/ccgo/v3 v3.12.6/go.mod h1:0Ji3ruvpFPpz+yu+1m0wk68pdr/LENABhTrDkMDWH6c= +modernc.org/ccgo/v3 v3.12.8/go.mod h1:Hq9keM4ZfjCDuDXxaHptpv9N24JhgBZmUG5q60iLgUo= +modernc.org/ccgo/v3 v3.12.11/go.mod h1:0jVcmyDwDKDGWbcrzQ+xwJjbhZruHtouiBEvDfoIsdg= +modernc.org/ccgo/v3 v3.12.14/go.mod h1:GhTu1k0YCpJSuWwtRAEHAol5W7g1/RRfS4/9hc9vF5I= +modernc.org/ccgo/v3 v3.12.18/go.mod h1:jvg/xVdWWmZACSgOiAhpWpwHWylbJaSzayCqNOJKIhs= +modernc.org/ccgo/v3 v3.12.20/go.mod h1:aKEdssiu7gVgSy/jjMastnv/q6wWGRbszbheXgWRHc8= +modernc.org/ccgo/v3 v3.12.21/go.mod h1:ydgg2tEprnyMn159ZO/N4pLBqpL7NOkJ88GT5zNU2dE= +modernc.org/ccgo/v3 v3.12.22/go.mod h1:nyDVFMmMWhMsgQw+5JH6B6o4MnZ+UQNw1pp52XYFPRk= +modernc.org/ccgo/v3 v3.12.25/go.mod h1:UaLyWI26TwyIT4+ZFNjkyTbsPsY3plAEB6E7L/vZV3w= +modernc.org/ccgo/v3 v3.12.29/go.mod h1:FXVjG7YLf9FetsS2OOYcwNhcdOLGt8S9bQ48+OP75cE= +modernc.org/ccgo/v3 v3.12.36/go.mod h1:uP3/Fiezp/Ga8onfvMLpREq+KUjUmYMxXPO8tETHtA8= +modernc.org/ccgo/v3 v3.12.38/go.mod h1:93O0G7baRST1vNj4wnZ49b1kLxt0xCW5Hsa2qRaZPqc= +modernc.org/ccgo/v3 v3.12.43/go.mod h1:k+DqGXd3o7W+inNujK15S5ZYuPoWYLpF5PYougCmthU= +modernc.org/ccgo/v3 v3.12.46/go.mod h1:UZe6EvMSqOxaJ4sznY7b23/k13R8XNlyWsO5bAmSgOE= +modernc.org/ccgo/v3 v3.12.47/go.mod h1:m8d6p0zNps187fhBwzY/ii6gxfjob1VxWb919Nk1HUk= +modernc.org/ccgo/v3 v3.12.50/go.mod h1:bu9YIwtg+HXQxBhsRDE+cJjQRuINuT9PUK4orOco/JI= +modernc.org/ccgo/v3 v3.12.51/go.mod h1:gaIIlx4YpmGO2bLye04/yeblmvWEmE4BBBls4aJXFiE= +modernc.org/ccgo/v3 v3.12.53/go.mod h1:8xWGGTFkdFEWBEsUmi+DBjwu/WLy3SSOrqEmKUjMeEg= +modernc.org/ccgo/v3 v3.12.54/go.mod h1:yANKFTm9llTFVX1FqNKHE0aMcQb1fuPJx6p8AcUx+74= +modernc.org/ccgo/v3 v3.12.55/go.mod h1:rsXiIyJi9psOwiBkplOaHye5L4MOOaCjHg1Fxkj7IeU= +modernc.org/ccgo/v3 v3.12.56/go.mod h1:ljeFks3faDseCkr60JMpeDb2GSO3TKAmrzm7q9YOcMU= +modernc.org/ccgo/v3 v3.12.57/go.mod h1:hNSF4DNVgBl8wYHpMvPqQWDQx8luqxDnNGCMM4NFNMc= +modernc.org/ccgo/v3 v3.12.60/go.mod h1:k/Nn0zdO1xHVWjPYVshDeWKqbRWIfif5dtsIOCUVMqM= +modernc.org/ccgo/v3 v3.12.66/go.mod h1:jUuxlCFZTUZLMV08s7B1ekHX5+LIAurKTTaugUr/EhQ= +modernc.org/ccgo/v3 v3.12.67/go.mod h1:Bll3KwKvGROizP2Xj17GEGOTrlvB1XcVaBrC90ORO84= +modernc.org/ccgo/v3 v3.12.73/go.mod h1:hngkB+nUUqzOf3iqsM48Gf1FZhY599qzVg1iX+BT3cQ= +modernc.org/ccgo/v3 v3.12.81/go.mod h1:p2A1duHoBBg1mFtYvnhAnQyI6vL0uw5PGYLSIgF6rYY= +modernc.org/ccgo/v3 v3.12.84/go.mod h1:ApbflUfa5BKadjHynCficldU1ghjen84tuM5jRynB7w= +modernc.org/ccgo/v3 v3.12.86/go.mod h1:dN7S26DLTgVSni1PVA3KxxHTcykyDurf3OgUzNqTSrU= +modernc.org/ccgo/v3 v3.12.90/go.mod h1:obhSc3CdivCRpYZmrvO88TXlW0NvoSVvdh/ccRjJYko= +modernc.org/ccgo/v3 v3.12.92/go.mod h1:5yDdN7ti9KWPi5bRVWPl8UNhpEAtCjuEE7ayQnzzqHA= +modernc.org/ccgo/v3 v3.13.1/go.mod h1:aBYVOUfIlcSnrsRVU8VRS35y2DIfpgkmVkYZ0tpIXi4= +modernc.org/ccgo/v3 v3.14.0/go.mod h1:hBrkiBlUwvr5vV/ZH9YzXIp982jKE8Ek8tR1ytoAL6Q= +modernc.org/ccgo/v3 v3.15.1/go.mod h1:md59wBwDT2LznX/OTCPoVS6KIsdRgY8xqQwBV+hkTH0= +modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w= +modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q= +modernc.org/libc v1.11.0/go.mod h1:2lOfPmj7cz+g1MrPNmX65QCzVxgNq2C5o0jdLY2gAYg= +modernc.org/libc v1.11.2/go.mod h1:ioIyrl3ETkugDO3SGZ+6EOKvlP3zSOycUETe4XM4n8M= +modernc.org/libc v1.11.5/go.mod h1:k3HDCP95A6U111Q5TmG3nAyUcp3kR5YFZTeDS9v8vSU= +modernc.org/libc v1.11.6/go.mod h1:ddqmzR6p5i4jIGK1d/EiSw97LBcE3dK24QEwCFvgNgE= +modernc.org/libc v1.11.11/go.mod h1:lXEp9QOOk4qAYOtL3BmMve99S5Owz7Qyowzvg6LiZso= +modernc.org/libc v1.11.13/go.mod h1:ZYawJWlXIzXy2Pzghaf7YfM8OKacP3eZQI81PDLFdY8= +modernc.org/libc v1.11.16/go.mod h1:+DJquzYi+DMRUtWI1YNxrlQO6TcA5+dRRiq8HWBWRC8= +modernc.org/libc v1.11.19/go.mod h1:e0dgEame6mkydy19KKaVPBeEnyJB4LGNb0bBH1EtQ3I= +modernc.org/libc v1.11.24/go.mod h1:FOSzE0UwookyT1TtCJrRkvsOrX2k38HoInhw+cSCUGk= +modernc.org/libc v1.11.26/go.mod h1:SFjnYi9OSd2W7f4ct622o/PAYqk7KHv6GS8NZULIjKY= +modernc.org/libc v1.11.27/go.mod h1:zmWm6kcFXt/jpzeCgfvUNswM0qke8qVwxqZrnddlDiE= +modernc.org/libc v1.11.28/go.mod h1:Ii4V0fTFcbq3qrv3CNn+OGHAvzqMBvC7dBNyC4vHZlg= +modernc.org/libc v1.11.31/go.mod h1:FpBncUkEAtopRNJj8aRo29qUiyx5AvAlAxzlx9GNaVM= +modernc.org/libc v1.11.34/go.mod h1:+Tzc4hnb1iaX/SKAutJmfzES6awxfU1BPvrrJO0pYLg= +modernc.org/libc v1.11.37/go.mod h1:dCQebOwoO1046yTrfUE5nX1f3YpGZQKNcITUYWlrAWo= +modernc.org/libc v1.11.39/go.mod h1:mV8lJMo2S5A31uD0k1cMu7vrJbSA3J3waQJxpV4iqx8= +modernc.org/libc v1.11.42/go.mod h1:yzrLDU+sSjLE+D4bIhS7q1L5UwXDOw99PLSX0BlZvSQ= +modernc.org/libc v1.11.44/go.mod h1:KFq33jsma7F5WXiYelU8quMJasCCTnHK0mkri4yPHgA= +modernc.org/libc v1.11.45/go.mod h1:Y192orvfVQQYFzCNsn+Xt0Hxt4DiO4USpLNXBlXg/tM= +modernc.org/libc v1.11.47/go.mod h1:tPkE4PzCTW27E6AIKIR5IwHAQKCAtudEIeAV1/SiyBg= +modernc.org/libc v1.11.49/go.mod h1:9JrJuK5WTtoTWIFQ7QjX2Mb/bagYdZdscI3xrvHbXjE= +modernc.org/libc v1.11.51/go.mod h1:R9I8u9TS+meaWLdbfQhq2kFknTW0O3aw3kEMqDDxMaM= +modernc.org/libc v1.11.53/go.mod h1:5ip5vWYPAoMulkQ5XlSJTy12Sz5U6blOQiYasilVPsU= +modernc.org/libc v1.11.54/go.mod h1:S/FVnskbzVUrjfBqlGFIPA5m7UwB3n9fojHhCNfSsnw= +modernc.org/libc v1.11.55/go.mod h1:j2A5YBRm6HjNkoSs/fzZrSxCuwWqcMYTDPLNx0URn3M= +modernc.org/libc v1.11.56/go.mod h1:pakHkg5JdMLt2OgRadpPOTnyRXm/uzu+Yyg/LSLdi18= +modernc.org/libc v1.11.58/go.mod h1:ns94Rxv0OWyoQrDqMFfWwka2BcaF6/61CqJRK9LP7S8= +modernc.org/libc v1.11.71/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw= +modernc.org/libc v1.11.75/go.mod h1:dGRVugT6edz361wmD9gk6ax1AbDSe0x5vji0dGJiPT0= +modernc.org/libc v1.11.82/go.mod h1:NF+Ek1BOl2jeC7lw3a7Jj5PWyHPwWD4aq3wVKxqV1fI= +modernc.org/libc v1.11.86/go.mod h1:ePuYgoQLmvxdNT06RpGnaDKJmDNEkV7ZPKI2jnsvZoE= +modernc.org/libc v1.11.87/go.mod h1:Qvd5iXTeLhI5PS0XSyqMY99282y+3euapQFxM7jYnpY= +modernc.org/libc v1.11.88/go.mod h1:h3oIVe8dxmTcchcFuCcJ4nAWaoiwzKCdv82MM0oiIdQ= +modernc.org/libc v1.11.98/go.mod h1:ynK5sbjsU77AP+nn61+k+wxUGRx9rOFcIqWYYMaDZ4c= +modernc.org/libc v1.11.101/go.mod h1:wLLYgEiY2D17NbBOEp+mIJJJBGSiy7fLL4ZrGGZ+8jI= +modernc.org/libc v1.12.0/go.mod h1:2MH3DaF/gCU8i/UBiVE1VFRos4o523M7zipmwH8SIgQ= +modernc.org/libc v1.13.1/go.mod h1:npFeGWjmZTjFeWALQLrvklVmAxv4m80jnG3+xI8FdJk= +modernc.org/libc v1.13.2/go.mod h1:npFeGWjmZTjFeWALQLrvklVmAxv4m80jnG3+xI8FdJk= +modernc.org/libc v1.14.1/go.mod h1:npFeGWjmZTjFeWALQLrvklVmAxv4m80jnG3+xI8FdJk= +modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc= +modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM= +modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.14.5/go.mod h1:YyX5Rx0WbXokitdWl2GJIDy4BrPxBP0PwwhpXOHCDLE= +modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= +modernc.org/tcl v1.10.0/go.mod h1:WzWapmP/7dHVhFoyPpEaNSVTL8xtewhouN/cqSJ5A2s= +modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.2.21/go.mod h1:uXrObx4pGqXWIMliC5MiKuwAyMrltzwpteOFUP1PWCc= +modernc.org/z v1.3.0/go.mod h1:+mvgLH814oDjtATDdT3rs84JnUIpkvAF5B8AVkNlE2g= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/hailo/fds.go b/hailo/fds.go index 96766ae..c14ecaf 100644 --- a/hailo/fds.go +++ b/hailo/fds.go @@ -20,7 +20,8 @@ import ( "encoding/json" "github.com/eliona-smart-building-assistant/go-utils/http" "github.com/eliona-smart-building-assistant/go-utils/log" - "hailo/conf" + "github.com/volatiletech/null/v8" + "hailo/apiserver" "strings" "sync" "time" @@ -118,16 +119,16 @@ type Diag struct { var tokens sync.Map // GetSpecs reads the specification for all Hailo smart devices from eliona endpoint -func GetSpecs(configuration conf.Config) (Specs, error) { +func GetSpecs(config apiserver.Configuration) (Specs, error) { request, err := http.NewRequestWithBearer( - configuration.FdsConfig.FdsServer+FdsSpecificationPath, - getToken(configuration), + null.StringFromPtr(config.FdsServer).String+FdsSpecificationPath, + getToken(config), ) if err != nil { return Specs{}, err } - specs, err := http.Read[Specs](request, time.Duration(configuration.RequestTimeout)*time.Second, true) + specs, err := http.Read[Specs](request, time.Duration(config.RequestTimeout)*time.Second, true) if err != nil { return specs, err } @@ -136,16 +137,17 @@ func GetSpecs(configuration conf.Config) (Specs, error) { } // GetDiag reads the diagnostic data for the given device id -func GetDiag(configuration conf.Config, deviceId string) (Diag, error) { +func GetDiag(config apiserver.Configuration, deviceId string) (Diag, error) { request, err := http.NewRequestWithBearer( - configuration.FdsConfig.FdsServer+FdsDiagnosticsPath+FdsIdParam+deviceId, - getToken(configuration), + + null.StringFromPtr(config.FdsServer).String+FdsDiagnosticsPath+FdsIdParam+deviceId, + getToken(config), ) if err != nil { return Diag{}, err } - diagnostics, err := http.Read[Diags](request, time.Duration(configuration.RequestTimeout)*time.Second, true) + diagnostics, err := http.Read[Diags](request, time.Duration(config.RequestTimeout)*time.Second, true) if err != nil { return Diag{}, err } @@ -153,16 +155,16 @@ func GetDiag(configuration conf.Config, deviceId string) (Diag, error) { } // GetStatus reads the status data for the given device id -func GetStatus(configuration conf.Config, deviceId string) (Status, error) { +func GetStatus(config apiserver.Configuration, deviceId string) (Status, error) { request, err := http.NewRequestWithBearer( - configuration.FdsConfig.FdsServer+FdsStatusPath+FdsIdParam+deviceId, - getToken(configuration), + null.StringFromPtr(config.FdsServer).String+FdsStatusPath+FdsIdParam+deviceId, + getToken(config), ) if err != nil { return Status{}, err } - statuses, err := http.Read[Statuses](request, time.Duration(configuration.RequestTimeout)*time.Second, true) + statuses, err := http.Read[Statuses](request, time.Duration(config.RequestTimeout)*time.Second, true) if err != nil { return Status{}, err } @@ -204,34 +206,34 @@ func isTokenValid(token string) bool { } // getToken creates a new token or delivers a previous token until this token is valid -func getToken(configuration conf.Config) string { - token, found := tokens.Load(configuration.Id) +func getToken(config apiserver.Configuration) string { + token, found := tokens.Load(config.Id) if found { if isTokenValid(token.(string)) { return token.(string) } } - token, _ = authenticate(configuration) - tokens.Store(configuration.Id, token) + token, _ = authenticate(config) + tokens.Store(config.Id, token) return token.(string) } // authenticate creates a new token -func authenticate(configuration conf.Config) (string, error) { +func authenticate(config apiserver.Configuration) (string, error) { log.Info("Hailo", "Create new Authentication token") request, err := http.NewPostRequest( - configuration.FdsConfig.AuthServer+AuthApiPath, + null.StringFromPtr(config.AuthServer).String+AuthApiPath, auth{ - UserName: configuration.FdsConfig.Name, - Password: configuration.FdsConfig.Password, + UserName: null.StringFromPtr(config.Username).String, + Password: null.StringFromPtr(config.Password).String, }, ) if err != nil { return "", err } - token, err := http.Do(request, time.Duration(configuration.AuthTimeout)*time.Second, true) + token, err := http.Do(request, time.Duration(config.AuthTimeout)*time.Second, true) if err != nil { return "", err } diff --git a/main.go b/main.go index 2cb6aa4..feebb9a 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,7 @@ package main import ( + "context" "github.com/eliona-smart-building-assistant/go-eliona/app" "github.com/eliona-smart-building-assistant/go-eliona/asset" "github.com/eliona-smart-building-assistant/go-eliona/dashboard" @@ -70,7 +71,7 @@ func main() { ) // At the end set all configuration inactive - conf.SetAllConfigsInactive() + _, _ = conf.SetAllConfigsInactive(context.Background()) log.Info("Hailo", "Terminate the app.") } diff --git a/openapi.yaml b/openapi.yaml index ca3568c..32c261f 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -54,6 +54,24 @@ paths: type: array items: $ref: '#/components/schemas/Configuration' + post: + tags: + - Configuration + summary: Creates an FDS endpoint + description: Creates an FDS endpoint. + operationId: postConfiguration + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Configuration' + responses: + 201: + description: Successfully created a new Hailo FDS endpoint + content: + application/json: + schema: + $ref: '#/components/schemas/Configuration' /configs/{config-id}: get: @@ -62,7 +80,7 @@ paths: summary: Get FDS endpoint description: Gets information about the FDS endpoint with the given id parameters: - - $ref: '#/components/parameters/ConfigId' + - $ref: '#/components/parameters/config-id' operationId: getConfigurationById responses: 200: @@ -74,18 +92,34 @@ paths: put: tags: - Configuration - summary: Creates or update an FDS endpoint - description: Creates an FDS endpoint configuration if no configuration with the same id already exists. If there is such an id the configuration is updated. + summary: Updates an FDS endpoint + description: Updates an FDS endpoint. parameters: - - $ref: '#/components/parameters/ConfigId' - operationId: putConfiguration + - $ref: '#/components/parameters/config-id' + operationId: putConfigurationById + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Configuration' responses: 200: - description: Successfully created a new or updated an existing configured Hailo FDS endpoint + description: Successfully updates a Hailo FDS endpoint content: application/json: schema: $ref: '#/components/schemas/Configuration' + delete: + tags: + - Configuration + summary: Deletes a FDS endpoint + description: Removes information about the FDS endpoint with the given id + parameters: + - $ref: '#/components/parameters/config-id' + operationId: deleteConfigurationById + responses: + 204: + description: Successfully deletes configured FDS endpoint /asset-mappings/: get: @@ -99,7 +133,8 @@ paths: required: false schema: type: integer - example: 4711 + format: int64 + responses: 200: description: Successfully returned asset mappings @@ -114,7 +149,7 @@ components: parameters: - ConfigId: + config-id: name: config-id in: path description: The id of the configured Hailo FDS endpoint @@ -122,6 +157,8 @@ components: required: true schema: type: integer + format: int64 + example: 4711 schemas: @@ -131,6 +168,7 @@ components: properties: id: type: integer + format: int64 description: Internal identifier for the configured endpoint (created automatically). This identifier have to use always if you remove or update existing configured endpoints. readOnly: true nullable: true @@ -180,6 +218,10 @@ components: type: integer description: Timeout in seconds for FDS server default: 120 + inactiveTimeout: + type: integer + description: Timeout for inactivity + default: 86400 # 1 day active: type: boolean readOnly: true diff --git a/sqlboiler.toml b/sqlboiler.toml index ef5ade6..5eb3e5f 100644 --- a/sqlboiler.toml +++ b/sqlboiler.toml @@ -1,25 +1,20 @@ -output = "db/public" -pkgname = "dbpublic" +output = "db/hailo" +pkgname = "dbhailo" add-global-variants = true wipe = true no-tests = true add-enum-types = true [psql] -dbname = "iot" +dbname = "postgres" host = "localhost" -port = 60001 +port = 5432 user = "postgres" pass = "secret" -schema = "public" +schema = "hailo" sslmode = "disable" whitelist = [ - "asset", "heap", "trend_0", "trend_agg", "pipeline", - "asset_type", "attribute_schema", - "dashboard", "widget", "widget_element", "widget_type", - "eliona_app", - "alarm", "alarm_cfg", "alarm_history", - "edge_bridge", "eliona_node", "iosys_access", "iosys_device", "mbus_access", "mbus_device" + "asset", "config" ] [[types]] @@ -36,9 +31,3 @@ type = "int" [types.replace] type = "int32" - -[aliases.tables.alarm_cfg] -up_plural = "AlarmConfigs" -up_singular = "AlarmConfig" -down_plural = "alarmConfigs" -down_singular = "alarmConfig" \ No newline at end of file diff --git a/utils.go b/utils.go index 2488a18..b813424 100644 --- a/utils.go +++ b/utils.go @@ -4,6 +4,7 @@ import ( "encoding/json" "flag" "fmt" + "hailo/apiserver" "hailo/conf" "hailo/hailo" "os" @@ -60,7 +61,7 @@ func determineArgs() args { } // printSpec gets and prints out the data for the specification -func printSpec(config conf.Config, spec hailo.Spec) { +func printSpec(config apiserver.Configuration, spec hailo.Spec) { fmt.Printf(" ---- Device %s ----\n", spec.DeviceId) pretty, _ := json.MarshalIndent(spec, "", "\t") fmt.Println(string(pretty))