comparison pkg/controllers/gauges.go @ 3194:eeff2cc4ff9d

controllers: re-factored the SQL filter to a tree like structure to be of more general use.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Wed, 08 May 2019 13:11:30 +0200
parents 54a3e40cfbed
children 9e087a495f41
comparison
equal deleted inserted replaced
3193:8329c6d3cf2a 3194:eeff2cc4ff9d
626 rw, fmt.Sprintf("error: Invalid ISRS code: %v", err), 626 rw, fmt.Sprintf("error: Invalid ISRS code: %v", err),
627 http.StatusBadRequest) 627 http.StatusBadRequest)
628 return 628 return
629 } 629 }
630 630
631 var fb filterBuilder 631 filters := filterAnd{
632 fb.stmt.WriteString(selectWaterlevelsSQL) 632 buildFilterTerm(
633 633 "fk_gauge_id = ($%d::char(2), $%d::char(3), $%d::char(5), $%d::char(5), $%d::int)",
634 fb.and( 634 isrs.CountryCode,
635 " fk_gauge_id = ($%d::char(2), $%d::char(3), $%d::char(5), $%d::char(5), $%d::int) ", 635 isrs.LoCode,
636 isrs.CountryCode, 636 isrs.FairwaySection,
637 isrs.LoCode, 637 isrs.Orc,
638 isrs.FairwaySection, 638 isrs.Hectometre,
639 isrs.Orc, 639 ),
640 isrs.Hectometre, 640 &filterOr{
641 ) 641 &filterNot{&filterTerm{format: "predicted"}},
642 642 buildFilterTerm(
643 fb.and( 643 `date_issue = (
644 `(NOT predicted 644 SELECT max(date_issue) FROM waterway.gauge_measurements
645 OR ( 645 WHERE fk_gauge_id = ($%d::char(2), $%d::char(3), $%d::char(5), $%d::char(5), $%d::int)`,
646 date_issue = ( 646 isrs.CountryCode,
647 SELECT max(date_issue) FROM waterway.gauge_measurements 647 isrs.LoCode,
648 WHERE fk_gauge_id = ($%d::char(2), $%d::char(3), $%d::char(5), $%d::char(5), $%d::int) 648 isrs.FairwaySection,
649 ) 649 isrs.Orc,
650 ))`, 650 isrs.Hectometre,
651 isrs.CountryCode, 651 ),
652 isrs.LoCode, 652 },
653 isrs.FairwaySection, 653 }
654 isrs.Orc,
655 isrs.Hectometre,
656 )
657 654
658 if from := req.FormValue("from"); from != "" { 655 if from := req.FormValue("from"); from != "" {
659 fromTime, err := time.Parse(models.ImportTimeFormat, from) 656 fromTime, err := time.Parse(models.ImportTimeFormat, from)
660 if err != nil { 657 if err != nil {
661 http.Error( 658 http.Error(
662 rw, fmt.Sprintf("error: Invalid from time: %v", err), 659 rw, fmt.Sprintf("error: Invalid from time: %v", err),
663 http.StatusBadRequest) 660 http.StatusBadRequest)
664 return 661 return
665 } 662 }
666 fb.and("measure_date >= $%d", fromTime) 663 filters = append(filters, buildFilterTerm("measure_date >= $%d", fromTime))
667 } 664 }
668 665
669 if to := req.FormValue("to"); to != "" { 666 if to := req.FormValue("to"); to != "" {
670 toTime, err := time.Parse(models.ImportTimeFormat, to) 667 toTime, err := time.Parse(models.ImportTimeFormat, to)
671 if err != nil { 668 if err != nil {
672 http.Error( 669 http.Error(
673 rw, fmt.Sprintf("error: Invalid from time: %v", err), 670 rw, fmt.Sprintf("error: Invalid from time: %v", err),
674 http.StatusBadRequest) 671 http.StatusBadRequest)
675 return 672 return
676 } 673 }
677 fb.and("measure_date <= $%d", toTime) 674 filters = append(filters, buildFilterTerm("measure_date <= $%d", toTime))
678 } 675 }
676
677 var stmt strings.Builder
678 var args []interface{}
679
680 stmt.WriteString(selectWaterlevelsSQL)
681 filters.serialize(&stmt, &args)
679 682
680 conn := middleware.GetDBConn(req) 683 conn := middleware.GetDBConn(req)
681 684
682 ctx := req.Context() 685 ctx := req.Context()
683 686
684 rows, err := conn.QueryContext(ctx, fb.stmt.String(), fb.args...) 687 rows, err := conn.QueryContext(ctx, stmt.String(), args...)
685 if err != nil { 688 if err != nil {
686 http.Error( 689 http.Error(
687 rw, fmt.Sprintf("error: %v", err), 690 rw, fmt.Sprintf("error: %v", err),
688 http.StatusInternalServerError) 691 http.StatusInternalServerError)
689 return 692 return