view pkg/imports/misc.go @ 4949:1d50ac8dd688 fairway-marks-import

More missing header lines.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 20 Feb 2020 18:14:09 +0100
parents 51e90370eced
children 5c43427fc2bf
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"
	"fmt"
	"strings"
)

type stringCounter map[string]int

func (sc stringCounter) String() string {
	var b strings.Builder
	for t, c := range sc {
		if b.Len() > 0 {
			b.WriteString(", ")
		}
		b.WriteString(fmt.Sprintf("%s: %d", t, c))
	}
	return b.String()
}

// Savepoint is a function wrapper to hide the details
// of managing database SAVEPOINTs.
// If the returned function is called with a callback
// the callback is run in a SAVEPOINT.
// If the callback returns w/o an error the SAVEPOINT
// is released. Otherwise the SAVEPOINT is rolled back.
func Savepoint(
	ctx context.Context,
	tx *sql.Tx,
	name string,
) func(func() error) error {

	var (
		savepoint = "SAVEPOINT " + name
		rollback  = "ROLLBACK TO SAVEPOINT " + name
		release   = "RELEASE SAVEPOINT " + name
	)

	return func(fn func() error) (err error) {
		if _, err = tx.ExecContext(ctx, savepoint); err != nil {
			return
		}
		var done bool
		defer func() {
			if !done {
				_, err2 := tx.ExecContext(ctx, rollback)
				if err == nil {
					err = err2
				}
			}
		}()
		if err = fn(); err == nil {
			done = true
			_, err = tx.ExecContext(ctx, release)
		}
		return
	}
}