view pkg/scheduler/boot.go @ 1995:59055c8301df

Move import queue to its own database namespace Authorisation of the import queue has to be handled differently from the waterway-related data in the waterway schema. This is easier to handle, if both are in their own schema/namespace.
author Tom Gottfried <tom@intevation.de>
date Thu, 24 Jan 2019 12:56:31 +0100
parents 8bbdad3f9af7
children c06a2e5397fc
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 scheduler

import (
	"context"
	"database/sql"
	"log"

	"gemma.intevation.de/gemma/pkg/auth"
	"gemma.intevation.de/gemma/pkg/config"
)

const (
	bootRole = "sys_admin"

	selectImportConfSQL = `
SELECT id, username, cron
FROM import.import_configuration
WHERE cron IS NOT NULL`

	scheduledIDsSQL = `
SELECT id from import.import_configuration
WHERE username = $1 AND cron IS NOT NULL`
)

func init() { go boot() }

// boot starts the scheduler with the configurations from
// the database which have a schedule.
func boot() {
	config.WaitReady()
	log.Println("info: booting scheduler from database.")
	ctx := context.Background()
	err := auth.RunAs(
		ctx, bootRole,
		func(conn *sql.Conn) error {
			rows, err := conn.QueryContext(ctx, selectImportConfSQL)
			if err != nil {
				return err
			}
			defer rows.Close()
			err = BootActions(func(ba *BoundAction) (bool, error) {
				if err != nil {
					return false, err
				}
				if !rows.Next() {
					return false, nil
				}
				var id int64
				if err = rows.Scan(
					&id,
					&ba.Name,
					&ba.Spec,
				); err != nil {
					return false, err
				}
				ba.CfgID = id
				return true, nil
			})
			if err != nil {
				return err
			}
			return rows.Err()
		})
	if err != nil {
		log.Printf("error: %v\n", err)
	}
}

// ScheduledUserIDs returns the IDs with a schedule for a given user.
func ScheduledUserIDs(
	ctx context.Context,
	conn *sql.Conn,
	user string,
) (map[int64]struct{}, error) {
	ids := map[int64]struct{}{}
	rows, err := conn.QueryContext(ctx, scheduledIDsSQL, user)
	if err != nil {
		return nil, nil
	}
	defer rows.Close()
	for rows.Next() {
		var id int64
		if err := rows.Scan(&id); err != nil {
			return nil, err
		}
		ids[id] = struct{}{}
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return ids, nil
}