changeset 2098:8a986d80e1c6

Approved gauge measuremnet imports: Removed an indirection layer accessing the columns of the CSV file.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 04 Feb 2019 11:34:09 +0100
parents 8b7dee291488
children 1baae9d31b3d
files pkg/imports/agm.go
diffstat 1 files changed, 69 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/imports/agm.go	Fri Feb 01 18:29:02 2019 +0100
+++ b/pkg/imports/agm.go	Mon Feb 04 11:34:09 2019 +0100
@@ -140,34 +140,66 @@
 		return nil, err
 	}
 
-	headerIndices := map[string]int{}
+	var (
+		fkGaugeIDIdx     = -1
+		measureDateIdx   = -1
+		fromIdx          = -1
+		languageCodeIdx  = -1
+		countryCodeIdx   = -1
+		dateIssueIdx     = -1
+		referenceCodeIdx = -1
+		valueIdx         = -1
+		predictedIdx     = -1
+		valueMinIdx      = -1
+		valueMaxIdx      = -1
+		dateInfoIdx      = -1
+		originatorIdx    = -1
+		unitIdx          = -1
+	)
 
+	headerFields := []struct {
+		idx  *int
+		name string
+	}{
+		{&fkGaugeIDIdx, "fk_gauge_id"},
+		{&measureDateIdx, "measure_date"},
+		{&fromIdx, "from"}, // "sender",
+		{&languageCodeIdx, "language_code"},
+		{&countryCodeIdx, "country_code"},
+		{&dateIssueIdx, "date_issue"},
+		{&referenceCodeIdx, "reference_code"},
+		{&valueIdx, "value"}, // "water_level",
+		{&predictedIdx, "predicted"},
+		// "is_waterlevel",
+		{&valueMinIdx, "value_min"},
+		{&valueMaxIdx, "value_max"},
+		{&dateInfoIdx, "date_info"},
+		{&originatorIdx, "originator"}, // "source_organization",
+		{&unitIdx, "unit"},
+	}
+
+nextHeader:
 	for i, f := range headers {
-		headerIndices[strings.Replace(
-			strings.ToLower(
-				strings.TrimSpace(f)), " ", "_", -1)] = i
+		h := strings.Replace(strings.ToLower(
+			strings.TrimSpace(f)), " ", "_", -1)
+
+		for j := range headerFields {
+			if headerFields[j].name == h {
+				if *headerFields[j].idx != -1 {
+					return nil, fmt.Errorf(
+						"There is more than one column namend '%s'", h)
+				}
+				*headerFields[j].idx = i
+				continue nextHeader
+			}
+		}
 	}
 
 	var missing []string
 
-	for _, m := range [...]string{
-		"fk_gauge_id",
-		"measure_date",
-		"from", // "sender",
-		"language_code",
-		"country_code",
-		"date_issue",
-		"reference_code",
-		"value", // "water_level",
-		"predicted",
-		// "is_waterlevel",
-		"value_min",
-		"value_max",
-		"date_info",
-		"originator", // "source_organization",
-	} {
-		if _, found := headerIndices[m]; !found {
-			missing = append(missing, m)
+	for i := range headerFields {
+		if headerFields[i].name != "unit" && *headerFields[i].idx == -1 {
+			missing = append(missing, headerFields[i].name)
 		}
 	}
 
@@ -177,11 +209,10 @@
 
 	inCm, _ := rescale("cm")
 	scaler := func(row []string) (func(float32) float32, error) {
-		idx, found := headerIndices["unit"]
-		if !found {
+		if unitIdx == -1 {
 			return inCm, nil
 		}
-		unit := row[idx]
+		unit := row[unitIdx]
 		if unit == "cm" {
 			return inCm, nil
 		}
@@ -227,7 +258,7 @@
 			return nil, fmt.Errorf("line %d: %v", line, err)
 		}
 
-		gids := row[headerIndices["fk_gauge_id"]]
+		gids := row[fkGaugeIDIdx]
 		gid, err := models.IsrsFromString(gids)
 		if err != nil {
 			return nil, fmt.Errorf("Invalid ISRS code line %d: %v", line, err)
@@ -239,54 +270,54 @@
 		args[3] = gid.Orc
 		args[4] = gid.Hectometre
 
-		md, err := guessDate(row[headerIndices["measure_date"]])
+		md, err := guessDate(row[measureDateIdx])
 		if err != nil {
 			return nil, fmt.Errorf("Invalid 'measure_date' line %d: %v", line, err)
 		}
 		args[5] = md
 
-		args[6] = row[headerIndices["from"]]
-		args[7] = row[headerIndices["language_code"]]
-		args[8] = row[headerIndices["country_code"]]
+		args[6] = row[fromIdx]
+		args[7] = row[languageCodeIdx]
+		args[8] = row[countryCodeIdx]
 
-		dis, err := guessDate(row[headerIndices["date_issue"]])
+		dis, err := guessDate(row[dateIssueIdx])
 		if err != nil {
 			return nil, fmt.Errorf("Invalid 'date_issue' line %d: %v", line, err)
 		}
 		args[9] = dis
 
-		args[10] = row[headerIndices["reference_code"]]
+		args[10] = row[referenceCodeIdx]
 
-		value, err := strconv.ParseFloat(row[headerIndices["value"]], 32)
+		value, err := strconv.ParseFloat(row[valueIdx], 32)
 		if err != nil {
 			return nil, fmt.Errorf("Invalid 'value' line %d: %v", line, err)
 		}
 		args[11] = convert(float32(value))
 
-		predicted := strings.ToLower(row[headerIndices["predicted"]]) == "true"
+		predicted := strings.ToLower(row[predictedIdx]) == "true"
 		args[12] = predicted
 
 		args[13] = true // is_waterlevel
 
-		valueMin, err := strconv.ParseFloat(row[headerIndices["value_min"]], 32)
+		valueMin, err := strconv.ParseFloat(row[valueMinIdx], 32)
 		if err != nil {
 			return nil, fmt.Errorf("Invalid 'value_min' line %d: %v", line, err)
 		}
 		args[14] = convert(float32(valueMin))
 
-		valueMax, err := strconv.ParseFloat(row[headerIndices["value_max"]], 32)
+		valueMax, err := strconv.ParseFloat(row[valueMaxIdx], 32)
 		if err != nil {
 			return nil, fmt.Errorf("Invalid 'value_max' line %d: %v", line, err)
 		}
 		args[15] = convert(float32(valueMax))
 
-		din, err := guessDate(row[headerIndices["date_info"]])
+		din, err := guessDate(row[dateInfoIdx])
 		if err != nil {
 			return nil, fmt.Errorf("Invalid 'date_info' line %d: %v", line, err)
 		}
 		args[16] = din
 
-		args[17] = row[headerIndices["originator"]]
+		args[17] = row[originatorIdx]
 
 		// args[18] (staging_done) is set to true outside the loop.