IN2090-ukesoppgaver: Uke 11

Programmering med SQL

Du velger selv om du vil l?se oppgavene med Python (3) eller Java. Oppgavene denne uken uvider koden skrevet som del av denne ukens videoer, og koden er tilgjengelig fra timeplanen i enkle filer, eller kan lastes ned som en Zip-fil som inneholder SQL-scriptene, Python-koden, Java-koden og Javas avhengigheter.

Merk: Koden kobler seg til din personlige database p? IFI, s? i likhet med tilkobling til databasene via psql m? man enten fjerninnlogge til en IFI-maskin, v?re p? IFIs WIFI eller sitte p? en IFI-maskin for ? kunne kj?re koden.

Om du fjerninnlogger kan koden lastes ned i bash slik:

wget /studier/emner/matnat/ifi/IN2090/h23/undervisningsmateriale/webshop.zip
unzip webshop.zip
cd webshop

For ? f? dataene inn i din personlige database, kj?r de to SQL-scriptene webshop.sql og data.sql som ligger i Zip-filen. Disse kan kj?res ved ? logge inn i din personlige database fra mappen med SQL-filene, og kj?re f?lgende fra psql:

\i webshop.sql
\i data.sql

Python

Dersom du velger Python m? programmene du skriver kj?res med Python 3. Dette gj?res p? f?lgende m?te:

python3 user_frontend.py

For Python kan det v?re (om du f?r en feilmelding om at psycopg2 ikke finnes) du ogs? m? installere biblioteket psycopg2, som gj?res ved ? kj?re:

pip3 install --user psycopg2-binary

Java

Dersom du velger ? l?se oppgaven med Java kan det v?re (om du f?r en ClassDefNotFoundError) at du m? ha med filen postgresql.jar n?r du kj?rer programmet. Filen ligger i webshop/java-mappen i Zip-filen som man kan laste ned over. Du kj?rer s? Java programmet (etter vanlig kompilering med javac) slik i Linux/Mac:

java -cp ".:postgresql.jar" UserFrontend

og slik i Windows:

java -cp ".;postgresql.jar" UserFrontend

Oppgave 1 – Forbedret s?k

I denne oppgaven skal du forbedre s?ket etter produkter. Brukeren skal kunne sortere resultatene, og skal kunne velge om sorteringen skal skje p? pris eller p? produktnavn, i tillegg skal brukeren kunne velge om sorteringen skal skje fra minst til st?rst eller st?rst til minst. Til slutt skal brukeren kunne velge en begrensning p? hvor mange produkter som skal vises. Merk at om brukeren ikke oppgir noe p? sp?rsm?lene, skal ingen sortering/begrensning skje. Et s?k skal da kunne se slik ut:

-- USER FRONTEND --
Please choose an option:
 1. Register
 2. Login
 3. Exit
Option: 2
 -- LOGIN --
Username: perh
Password: per123
Welcome Per Hansen
 -- SEARCH --
Search: 
Category: games
How should the results be sorted?
1. by price
2. by name
Sorting: 1
Sort according to:
1. Ascending order
2. Descending order
Ordering: 1
Limit: 2
 -- RESULTS --

=== Realm of Battle Skill ===
Product ID: 13
Price: 19.95
Category: games
Description: An MMORPG

=== Star Fights 3 ===
Product ID: 2
Price: 15.39
Category: games
Description: A space simulator

Tips: Merk at man m? n? holde styr p? hvilke “placeholdere” man har lagt til i sp?rringen og ikke (avhengig av brukerens input). I Python kan det derfor v?re lurt ? bruke navngitte “placeholders” som beskrevet i ukens videoer. For Java blir dette litt mer komplisert, siden Javas JDBC ikke st?tter navngitte parametre. Her kan man derimot bruke en teller (f.eks. int count=0) og s? ?ke denne for hver “placeholder” man substituerer inne en verdi for. F.eks.~som i koden her:

String q = "SELECT * FROM ws.products WHERE name LIKE ?";
if (min_price != null)
    q += " AND price <= ?";
if (max_price != null)
    q += " AND price >= ?";
q += ";";

PrepareStatement stmt = connection.prepareStatement(q);
stmt.setString(1, name);
int count = 2;
if (min_price != null)
    stmt.setFloat(count++, min_price);
if (max_price != null)
    stmt.setFloat(count++, max_price);

Oppgave 2 – Bestilling av produkter

I denne oppgaven skal du implementere order_products(conn, username) (Python) eller orderProducts(Connection connection, String username) (Java). Denne metoden blir kalt etter at en bruker har s?kt etter produkter. Denne metoden skal sp?rre brukeren om hvilket produkt brukeren ?nsker ? bestille basert p? pid (produktets ID), og deretter hvor mange av dette produktet som skal bestilles. S? skal metoden kj?re en INSERT-kommando som setter bestillingen inn i ws.orders-tabellen.

Merk at man vet brukernavnet til brukeren som skal bestille produketet, men i ws.orders skal man legge in brukerens uid.

En bestilling kan se slik ut (og er en forsettelse av s?ket vist over), hvor brukeren bestiller 5 eksemplarer av spillet med pid lik 2, alts? Star Fights 3:

[...]
 -- RESULTS --

=== Realm of Battle Skill ===
Product ID: 13
Price: 19.95
Category: games
Description: An MMORPG


=== Star Fights 3 ===
Product ID: 2
Price: 15.39
Category: games
Description: A space simulator


Order (Product ID): 2   
How many: 5
Product(s) ordered.

Oppgave 3 – Regninger

I denne og neste oppgave skal vi jobbe med et nytt program, Administrator, som er tiltenkt de ansatte i Webshop. S? last ned f?lgende Zip-fil p? samme m?te som beskrevet over.

Filen inneholder i likhet med forrige et skelett-program. I denne oppgaven skal du implementere funksjonen make_bills(conn) (for Python) eller metoden makeBills(Connection) (for Java) som genererer regninger for brukere. Funksjonen skal sp?rre brukeren av programmet om et brukernavn. Dersom brukeren oppgir et brukernavn skal programmet s? generere en regning for denne brukeren p? f?lgende format:

Name: <navn>
Address: <adresse>
Total due: <total>

hvor <navn> er brukerens navn, <adresse> er brukerens adresse, og <total> er mengden penger brukeren skylder, alts? summen av alle produktene som brukeren har bestilt men enn? ikke betalt for (husk at en bestilling kan inneholde flere av samme produkt via num-kolonnen).

F.eks.~kan output da se slik ut:

-- ADMINISTRATOR --
Please choose an option:
 1. Create bills
 2. Insert new product
 3. Exit
Option: 1
 -- BILLS --
Username: test

---Bill---
Name: Tester
Address: Teststreet 1
Total due: 25.0

Dersom brukeren ikke oppgir et brukernavn skal programmet generere en regning for alle brukere i databasen. F.eks. kan output da se slik ut (merk ingen input for Username:):

-- ADMINISTRATOR --
Please choose an option:
 1. Create bills
 2. Insert new product
 3. Exit
Option: 1
 -- BILLS --
Username: 

---Bill---
Name: Carl Smith
Address: Streetroad 34, 1234 Townplace
Total due: 404.88

---Bill---
Name: Mary Sagan
Address: Placestreet 12B, 4356 Nicetown
Total due: 259.91

---Bill---
Name: Tester
Address: Teststreet 1
Total due: 25.0

Oppgave 4 – Sette inn nye produkter

I denne oppgaven skal du implementere funksjonen insert_product(conn) (for Python) eller metoden insertProducts(Connection) (for Java) som lar brukeren sette inn nye produkter i Webshopens produktkatalog (som da er ws.products-tabellen). Brukeren skal bli spurt om navn og pris p? produktet, navnet p? kategorien produktet tilh?rer, samt en mulig beskrivelse.

Programmet skal s? sette dette produktet inn i ws.products-tabellen. En kj?ring kan da se slik ut:

-- ADMINISTRATOR --
Please choose an option:
 1. Create bills
 2. Insert new product
 3. Exit
Option: 2

 -- INSERT NEW PRODUCT --
Product name: Juice
Price: 2.3
Category: food
Description: Fresh orange juice
New product Juice inserted.

Etter dette skal det finnes et nytt tuppel i tabellen ws.products med name lik Juice, price lik 2.3 og description lik Fresh orange juice.

Merk at pid-kolonnen i ws.products er satt til SERIAL, s? verdien for denne genereres automatisk. Merk ogs? at brukeren oppgir navnet p? kategorien, men i ws.products-tabellen skal vi ha cid, s? man m? alts? finne cid-verdien basert p? kategori-navnet fra brukeren gjennom en SELECT-sp?rring (husk at dette kan gj?res ved ? bruke SELECT i en INSERT-sp?rring).