Mercurial > gemma
view pkg/imports/config.go @ 1704:897d4d8316ad
Import configuration: Made extra attributes updatable, too.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Mon, 07 Jan 2019 15:34:34 +0100 |
parents | 49b89575ab31 |
children | dcbe2a7dc532 |
line wrap: on
line source
// This is Free Software under GNU Affero General Public License v >= 3.0 // without warranty, see README.md and license for details. // // SPDX-License-Identifier: AGPL-3.0-or-later // License-Filename: LICENSES/AGPL-3.0.txt // // Copyright (C) 2018 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> package imports import ( "context" "database/sql" "encoding/json" "fmt" "github.com/robfig/cron" "gemma.intevation.de/gemma/pkg/auth" ) type ( // CronSpec is a string containing a cron line. CronSpec string // ImportKind is a string which has to be one // of the registered import types. ImportKind string // ConfigAttributes is a map of optional key/value attributes // of an import configuration. ConfigAttributes map[string]string // Config is JSON serialized form of a import configuration. Config struct { // Kind is the import type. Kind ImportKind `json:"kind"` // SendEMail indicates if a mail should be be send // when the import was changed to states // 'pending' or 'failed'. SendEMail bool `json:"send-email"` // AutoAccept indicates that an import // automatically will change from state // 'pending' to state 'accepted'. AutoAccept bool `json:"auto-accept"` // Cron is the cron schedule // of this configuration if this value is not // nil. If nil the import is not scheduled. Cron *CronSpec `json:"cron"` // URL is an optional URL used by the import. URL *string `json:"url"` // Attributes are optional key/value pairs for a configuration. Attributes ConfigAttributes `json:"attributes,omitempty"` } // IDConfig is the same as Config with an ID. // Mainly used for server delivered configurations. IDConfig struct { ID int64 `json:"id"` User string `json:"user"` Kind ImportKind `json:"kind"` SendEMail bool `json:"send-email"` AutoAccept bool `json:"auto-accept"` Cron *CronSpec `json:"cron,omitempty"` URL *string `json:"url,omitempty"` Attributes ConfigAttributes `json:"attributes,omitempty"` } ) // Get fetches a value for given key out of the configuration. // If the key was not found the bool component of the return value // return false. func (ca ConfigAttributes) Get(key string) (string, bool) { if ca == nil { return "", false } value, found := ca[key] return value, found } // UnmarshalJSON checks if the incoming string // is a registered import type. func (ik *ImportKind) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } if !HasImportKindName(s) { return fmt.Errorf("Unknown kind '%s'", s) } *ik = ImportKind(s) return nil } // UnmarshalJSON checks if the incoming string is // a valid cron line. func (cs *CronSpec) UnmarshalJSON(data []byte) error { var spec string if err := json.Unmarshal(data, &spec); err != nil { return err } if _, err := cron.Parse(spec); err != nil { return err } *cs = CronSpec(spec) return nil } const ( configUser = "sys_admin" loadConfigSQL = ` SELECT username, kind, send_email, auto_accept, cron, url FROM waterway.import_configuration WHERE id = $1` loadConfigAttributesSQL = ` SELECT k, v FROM waterway.import_configuration_attributes WHERE import_configuration_id = $1` ) func loadIDConfig(id int64) (*IDConfig, error) { ctx := context.Background() cfg := &IDConfig{ID: id} err := auth.RunAs(ctx, configUser, func(conn *sql.Conn) error { var kind ImportKind var cron, url sql.NullString if err := conn.QueryRowContext(ctx, loadConfigSQL, id).Scan( &cfg.User, &kind, &cfg.SendEMail, &cfg.AutoAccept, &cron, &url, ); err != nil { return err } cfg.Kind = ImportKind(kind) if cron.Valid { c := CronSpec(cron.String) cfg.Cron = &c } if url.Valid { cfg.URL = &url.String } // load the extra attributes. rows, err := conn.QueryContext(ctx, loadConfigAttributesSQL, id) if err != nil { return err } defer rows.Close() var attributes map[string]string for rows.Next() { var k, v string if err = rows.Scan(&k, &v); err != nil { return err } if attributes == nil { attributes = map[string]string{} } attributes[k] = v } if err = rows.Err(); err != nil { return err } if len(attributes) > 0 { cfg.Attributes = attributes } return nil }) switch { case err == sql.ErrNoRows: return nil, nil case err != nil: return nil, err } return cfg, nil }