Server-Side Scripting/Key-Value Databases/Go

routes/lesson11.go edit

// This program creates and displays a temperature database
// with options to insert, update, and delete records.
//
// References:
//  https://golang.org/doc/
//  https://pkg.go.dev/github.com/go-redis/redis/v8
//
// Requires a Redis installation to manage the database.
// Use of a Docker container is recommended.
// See https://en.wikiversity.org/wiki/Docker/Redis .
// If both the Go website and Redis are running in containers, 
// use 172.17.0.2 for the redis host address.
// If the Go website and/or Redis are running locally, use 127.0.0.1
// for the Redis host address.

package routes

import (
    "html/template"
    "log"
    "net/http"
    "path/filepath"
    "github.com/go-redis/redis"
)

const HOST11 = "127.0.0.1:6379"
const PASSWORD11 = ""
const DATABASE11 = 0

func Lesson11(response http.ResponseWriter, request *http.Request) {
	response.Header().Set("Content-Type", "text/html; charset=utf-8")

    type Data struct {
		Table  template.HTML
	}
	
	result := ""

    switch request.Method {
        case "GET":
            result = processGet11()
        case "POST":
            result = processPost11(request)
        default:
            result = "Unexpected request method: " + request.Method
    }

	data := Data{template.HTML(result)}
	path := filepath.Join("templates", "lesson11.html")
	parsed, _ := template.ParseFiles(path)
	parsed.Execute(response, data)
}

func processGet11() string {
    result := getData11()
    return result
}

func processPost11(request *http.Request) string {
    country := request.FormValue("country")
    temperature := request.FormValue("temperature")

    if !countryExists11(country) {
        insertCountry11(country, temperature)
    } else if (temperature != "") {
        updateCountry11(country, temperature)
    } else {
        deleteCountry11(country)
    }

    result := getData11()
    return result
}

func getData11() string {
    client := redis.NewClient(&redis.Options{
        Addr:     HOST11,
        Password: PASSWORD11,
        DB:       DATABASE11,
    })
    
    result := "<table><tr><th>Country</th>"
    result += "<th>Temperature</th></tr>"

    iterator := client.Scan(0, "", 0).Iterator()
    for iterator.Next() {
        country := iterator.Val()
        temperature, err := client.Get(country).Result()
        if err != nil {
            log.Fatal(err)
        }
        
        result += "<tr><td>" + country + "</td>"
        result += "<td>" + temperature + "</td></tr>"
    }

    result += "</table>"
    return result
}

func countryExists11(country string) bool {
    client := redis.NewClient(&redis.Options{
        Addr:     HOST11,
        Password: PASSWORD11,
        DB:       DATABASE11,
    })

    result, err := client.Exists(country).Result()
    if err != nil {
        log.Fatal(err)
    }

    return result == 1
}

func insertCountry11(country string, temperature string) {
    client := redis.NewClient(&redis.Options{
        Addr:     HOST11,
        Password: PASSWORD11,
        DB:       DATABASE11,
    })

    err := client.Set(country, temperature, 0).Err()
    if err != nil {
        log.Fatal(err)
    }
}

func updateCountry11(country string, temperature string) {
    client := redis.NewClient(&redis.Options{
        Addr:     HOST11,
        Password: PASSWORD11,
        DB:       DATABASE11,
    })

    err := client.Set(country, temperature, 0).Err()
    if err != nil {
        log.Fatal(err)
    }
}

func deleteCountry11(country string) {
    client := redis.NewClient(&redis.Options{
        Addr:     HOST11,
        Password: PASSWORD11,
        DB:       DATABASE11,
    })

    err := client.Del(country).Err()
    if err != nil {
        log.Fatal(err)
    }
}

templates/lesson11.html edit

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Lesson 11</title>
    <link rel="stylesheet" href="styles.css">
</head>

<body>
    <h1>Temperature Data Entry</h1>
    <p>Enter country and temperature. Enter again to update.</p>
    <p>Enter country without temperature to delete.</p>
    <form method="POST">
        <p><label for="country">Country:</label>
            <input type="text" id="country" name="country" required>
        </p>
        <p><label for="stop">Temperature:</label>
            <input type="text" id="temperature" name="temperature">
        </p>
        <p><input type="submit" name="submit" value="Submit"></p>
    </form>
    <hr>
    {{.Table}}
</body>
</html>

Try It edit

See Server-Side Scripting/Routes and Templates/Go to create a test environment.