Mercurial > gemma
view pkg/controllers/common.go @ 5333:6c0f40676984 extented-report
Run xlsx templating in a read-only transaction.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Tue, 01 Jun 2021 00:37:03 +0200 |
parents | 6521c962a7b6 |
children | 5f47eeea988d |
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) 2019 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> package controllers import ( "fmt" "log" "strconv" "strings" "github.com/jackc/pgx/pgtype" ) type ( filterNode interface { serialize(*strings.Builder, *[]interface{}) } filterTerm struct { format string args []interface{} } filterNot struct { filterNode } filterAnd []filterNode filterOr []filterNode ) func (ft *filterTerm) serialize(stmt *strings.Builder, args *[]interface{}) { indices := make([]interface{}, len(ft.args)) for i := range indices { indices[i] = len(*args) + i + 1 } fmt.Fprintf(stmt, ft.format, indices...) *args = append(*args, (*ft).args...) } func buildFilterTerm(format string, args ...interface{}) *filterTerm { return &filterTerm{format: format, args: args} } func (fa filterAnd) serialize(stmt *strings.Builder, args *[]interface{}) { for i, node := range fa { if i > 0 { stmt.WriteString(" AND ") } stmt.WriteByte('(') node.serialize(stmt, args) stmt.WriteByte(')') } } func (fo filterOr) serialize(stmt *strings.Builder, args *[]interface{}) { for i, node := range fo { if i > 0 { stmt.WriteString(" OR ") } stmt.WriteByte('(') node.serialize(stmt, args) stmt.WriteByte(')') } } func (fn *filterNot) serialize(stmt *strings.Builder, args *[]interface{}) { stmt.WriteString("NOT (") fn.filterNode.serialize(stmt, args) stmt.WriteByte(')') } func toInt8Array(txt string) *pgtype.Int8Array { parts := strings.Split(txt, ",") var ints []int64 for _, part := range parts { part = strings.TrimSpace(part) v, err := strconv.ParseInt(part, 10, 64) if err != nil { continue } ints = append(ints, v) } var ia pgtype.Int8Array if err := ia.Set(ints); err != nil { log.Printf("warn: %v\n", err) return nil } return &ia } func sliceToTextArray(s []string) *pgtype.TextArray { if len(s) == 0 { return nil } var ta pgtype.TextArray if err := ta.Set(s); err != nil { log.Printf("warn: %v\n", err) return nil } return &ta } func toTextArray(txt string, allowed []string) *pgtype.TextArray { parts := strings.Split(txt, ",") var accepted []string for _, part := range parts { if part = strings.ToLower(strings.TrimSpace(part)); len(part) == 0 { continue } for _, a := range allowed { if part == a { accepted = append(accepted, part) break } } } return sliceToTextArray(accepted) } func splitUpper(s string) []string { s = strings.Map(func(r rune) rune { if ('A' <= r && r <= 'Z') || r == ',' { return r } return -1 }, strings.ToUpper(s)) return strings.FieldsFunc(s, func(r rune) bool { return r != ',' }) }