From b2d36d13e6d9488a41cacc075642ccf694d6041e Mon Sep 17 00:00:00 2001
From: Alexander Hinneburg <alexander.hinneburg@informatik.uni-halle.de>
Date: Fri, 21 Jun 2024 17:21:30 +0200
Subject: [PATCH] pgrest app mit elm example

---
 .gitignore                  |  2 +
 README.md                   | 25 ++++++-----
 docker-compose.yml          | 12 ++---
 elm/elm.json                | 27 ++++++++++++
 elm/src/Main.elm            | 88 +++++++++++++++++++++++++++++++++++++
 env-example                 |  6 ++-
 init/00-0_init_postgres.sh  | 15 +++----
 init/00-1_init_template1.sh |  4 +-
 init/04-presidents.sql      |  4 +-
 9 files changed, 151 insertions(+), 32 deletions(-)
 create mode 100644 elm/elm.json
 create mode 100644 elm/src/Main.elm

diff --git a/.gitignore b/.gitignore
index 3fe4846..b556be7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
 pg-data/*
 .env
+elm/elm-stuff
+elm/index.html
\ No newline at end of file
diff --git a/README.md b/README.md
index 05cd88b..1fb3df7 100644
--- a/README.md
+++ b/README.md
@@ -5,9 +5,9 @@ Der Container installiert ein Postgres-DBMS in der Version 11.2 mit mehreren Üb
 ## Installation
 Zum Arbeiten mit Docker brauchen sie  Administrator-Rechte oder sie müssen in der Gruppe `docker` sein.
 1. Installieren sie [Docker Community Edition](https://docs.docker.com/install/) und [Docker-Compose](https://docs.docker.com/compose/install/).
-2. Laden sie sich dieses Projekt auf ihren Computer, entpacken sie es und wechseln sie in das Verzeichnis `edb-pg-adm`.
+2. Laden sie sich dieses Projekt auf ihren Computer, entpacken sie es und wechseln sie in das Verzeichnis `www-pgrest`.
 3. Kopieren sie die Datei `env-example` nach `.env` und editieren sie `.env` um die Passwörter für den Datenbankzugriff zu setzen und den Port für die Adminer-Web-Applikation festzulegen.
-4. Führen sie in dem Verzeichnis `edb-pg-adm` in einer Shell das folgende Kommando aus, um den Container zu starten
+4. Führen sie in dem Verzeichnis `www-pgrest` in einer Shell das folgende Kommando aus, um den Container zu starten
 ```
 docker-compose up
 ```
@@ -17,12 +17,15 @@ Beim ersten Start werden die Container für Postgres und Adminer von [hub.docker
 
 Wenn der Docker-Container gestartet wurde (wie in Schritt 4 beschrieben) können mit einem Browser auf Adminer zu greifen. Wenn sie den Container auf ihren Computer installiert und den Port 80 gesetzt haben, ist der Link [http://localhost:80](http://localhost:80).
 
-Sie können sich als der Nutzer `student_gast` mit dem Passwort einloggen, dass sie in der Datei `.env` vorgegeben haben.
-In der Datenbank `postgres` sind folgende Datenbankschemata installiert:
-- `student_public` mit den Tabellen aus der Vorlesung
-- `empdept_public`
-- `komponist`
-- `maerchen`
-- `presidents`
-- `sakila`
-- `auto_motorcycle`    
+Sie können sich als der Nutzer mit dem Passwort einloggen, dass sie in der Datei `.env` vorgegeben haben.
+In der Datenbank `postgres` sind folgende Datenbankschemata installiert `presidents`. 
+
+Wenn alle Containter gestartet sind, können Sie mit dem Befehl
+```
+curl localhost:3000/president
+```
+den Inhalt den Tabelle `president` abfragen und das Ergebnis wird im Json-Format verpackt zurückgegeben.
+
+Im Verzeichnis elm ist ein Beispielprogramm, dass die Tabelle `president` abfragt und die Namen der Presidenten ausgibt. Die Abgabe nutzt `http://localhost:3000/president`. Wenn die o.g. Docker-Container laufen, können Sie das Elm-Programm mit einem lokalen Web-Server ausführen und bekommen das Ergebnis.
+
+
diff --git a/docker-compose.yml b/docker-compose.yml
index 57eb18d..090603c 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -9,9 +9,9 @@ services:
     restart: always
     environment:
      - POSTGRES_PASSWORD
-     - STUDENT_PASSWORD
-     - STUDENT_GAST
-     - DB_NAME
+     - APP_PASSWORD
+     - APP_USER
+     - APP_DB_NAME
     volumes:
      - "./pg-data:/var/lib/postgresql/data"
      - "./init:/docker-entrypoint-initdb.d"
@@ -33,9 +33,9 @@ services:
     depends_on:
       - db
     environment:
-      PGRST_DB_URI: postgres://$STUDENT_GAST:$STUDENT_PASSWORD@db:$DB_PORT/$DB_NAME
-      PGRST_DB_SCHEMA: president_public
-      PGRST_DB_ANON_ROLE: $STUDENT_GAST
+      PGRST_DB_URI: postgres://$APP_USER:$APP_PASSWORD@db:$APP_DB_PORT/postgres
+      PGRST_DB_SCHEMA: $APP_DB_SCHEMA
+      PGRST_DB_ANON_ROLE: $APP_USER
       PGRST_SERVER_PORT: 3000
     ports:
       - 3000:3000
diff --git a/elm/elm.json b/elm/elm.json
new file mode 100644
index 0000000..785c5be
--- /dev/null
+++ b/elm/elm.json
@@ -0,0 +1,27 @@
+{
+    "type": "application",
+    "source-directories": [
+        "src"
+    ],
+    "elm-version": "0.19.1",
+    "dependencies": {
+        "direct": {
+            "elm/browser": "1.0.2",
+            "elm/core": "1.0.5",
+            "elm/html": "1.0.0",
+            "elm/http": "2.0.0",
+            "elm/json": "1.1.3"
+        },
+        "indirect": {
+            "elm/bytes": "1.0.8",
+            "elm/file": "1.0.5",
+            "elm/time": "1.0.0",
+            "elm/url": "1.0.0",
+            "elm/virtual-dom": "1.0.3"
+        }
+    },
+    "test-dependencies": {
+        "direct": {},
+        "indirect": {}
+    }
+}
diff --git a/elm/src/Main.elm b/elm/src/Main.elm
new file mode 100644
index 0000000..4945a39
--- /dev/null
+++ b/elm/src/Main.elm
@@ -0,0 +1,88 @@
+module Main exposing (..)
+
+import Browser
+import Html exposing (Html, button, div, text)
+import Html.Events exposing (onClick)
+import Http
+import Json.Decode exposing (Decoder, map6, field, int, string, list, nullable)
+
+
+type alias Model =
+    { presidents : Maybe (List President) }
+
+type alias President =
+ {
+  pres_name:String,
+  birth_year:Int ,
+  years_serv:Int,
+  death_age:Maybe Int,
+  party:String,
+  state_born:String
+ }
+
+init : () -> (Model, Cmd Msg)
+init _ =
+    ({ presidents = Nothing }, getPresidents)
+
+
+getPresidents : Cmd Msg
+getPresidents =
+  Http.get
+    { url = "http://localhost:3000/president"
+    , expect = Http.expectJson GotPresidents presidentsDecoder
+    }
+
+
+presidentsDecoder : Decoder (List President)
+presidentsDecoder =
+  list (
+   (map6 President
+    (field "pres_name" string)
+    (field "birth_year" int)
+    (field "years_serv" int)
+    (field "death_age" (nullable int))
+    (field "party" string)
+    (field "state_born" string)
+   )
+  )
+
+type Msg =
+    GotPresidents (Result Http.Error (List President)) 
+
+
+update : Msg -> Model ->  (Model, Cmd Msg)
+update msg model =
+    case msg of
+        GotPresidents result ->
+          case result of
+              Ok l -> 
+                ({ model | presidents = Just l }, Cmd.none)
+              Err _ -> 
+                ({ model | presidents = Nothing }, Cmd.none)
+
+
+view : Model -> Html Msg
+view model =
+    div []
+        (
+        case model.presidents of
+            Just l ->
+              List.map (\p -> div [] [text p.pres_name])  l 
+            Nothing ->
+              []
+        ) 
+        
+
+
+main =
+  Browser.element
+    { init = init
+    , update = update
+    , subscriptions = subscriptions
+    , view = view
+    }
+
+
+subscriptions : Model -> Sub Msg
+subscriptions model =
+  Sub.none
diff --git a/env-example b/env-example
index a162704..77ff2dd 100644
--- a/env-example
+++ b/env-example
@@ -6,7 +6,11 @@
 # the pg_data directory is empty or not existing.
 
 POSTGRES_PASSWORD=change-this!
-STUDENT_PASSWORD=change-this-too!
+APP_USER=myappuser
+APP_PASSWORD=change-this-too!
+APP_DB_NAME=myappdb
+APP_DB_PORT=5432
+APP_DB_SCHEMA=president_public
 
 # Access adminer over the specified port, e.g. http://localhost:80/
 ADMINER_PORT=80
diff --git a/init/00-0_init_postgres.sh b/init/00-0_init_postgres.sh
index 06ff2a1..1960fa7 100755
--- a/init/00-0_init_postgres.sh
+++ b/init/00-0_init_postgres.sh
@@ -2,21 +2,18 @@
 set -e
 
 psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
-  CREATE ROLE student
+  CREATE ROLE app
     WITH
     NOLOGIN
   ;
 
-  CREATE ROLE ${STUDENT_GAST}
+  CREATE ROLE ${APP_USER}
     WITH
     LOGIN
-    PASSWORD '${STUDENT_PASSWORD}'
-    IN ROLE student
+    PASSWORD '${APP_PASSWORD}'
+    IN ROLE app
   ;
-  REVOKE ALL PRIVILEGES ON DATABASE postgres FROM student, ${STUDENT_GAST};
-  GRANT CONNECT ON DATABASE postgres TO student;
+  REVOKE ALL PRIVILEGES ON DATABASE postgres FROM app, ${APP_USER};
+  GRANT CONNECT ON DATABASE postgres TO app;
 
-  -- REVOKE ALL ON SCHEMA public FROM public;
-  -- REVOKE ALL ON ALL TABLES IN SCHEMA public FROM public, student, ${STUDENT_GAST};
-  -- DROP SCHEMA public;
 EOSQL
diff --git a/init/00-1_init_template1.sh b/init/00-1_init_template1.sh
index de6804d..4a696b6 100755
--- a/init/00-1_init_template1.sh
+++ b/init/00-1_init_template1.sh
@@ -2,7 +2,5 @@
 set -e
 
 psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "template1" <<-EOSQL
-   REVOKE ALL PRIVILEGES ON DATABASE template1 FROM student, ${STUDENT_GAST};
-   -- REVOKE ALL ON SCHEMA public FROM public;
-   -- REVOKE ALL ON ALL TABLES IN SCHEMA public FROM public, student, ${STUDENT_GAST};
+   REVOKE ALL PRIVILEGES ON DATABASE template1 FROM app, ${APP_USER};
 EOSQL
diff --git a/init/04-presidents.sql b/init/04-presidents.sql
index b8c3b4d..7bac2e1 100644
--- a/init/04-presidents.sql
+++ b/init/04-presidents.sql
@@ -631,6 +631,6 @@ insert into  Election values (2020,'Trump D J','Republican',232,'L');
 
 --   ##################################################################
 commit;
-GRANT USAGE ON SCHEMA president_public TO student;
-GRANT SELECT ON ALL TABLES IN SCHEMA president_public to student;
+GRANT USAGE ON SCHEMA president_public TO app;
+GRANT SELECT ON ALL TABLES IN SCHEMA president_public to app;
 
-- 
GitLab