This repository has been archived on 2025-07-20. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
fsad/assignment4/src/main/java/net/akpain/BooksDatabaseService.java
AKP 688da71131
Fix small bug (ignore if book is on loan or not)
Signed-off-by: AKP <tom@tdpain.net>
2023-05-01 02:31:54 +01:00

165 lines
5.3 KiB
Java

package net.akpain;/*
* BooksDatabaseService.java
*
* The service threads for the books database server.
* This class implements the database access service, i.e. opens a JDBC connection
* to the database, makes and retrieves the query, and sends back the result.
*
* author: 2430671
*
*/
import java.io.*;
//import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Arrays;
import java.util.Properties;
import java.util.StringTokenizer;
import java.sql.*;
import javax.sql.rowset.*;
//Direct import of the classes CachedRowSet and CachedRowSetImpl will fail becuase
//these clasess are not exported by the module. Instead, one needs to impor
//javax.sql.rowset.* as above.
public class BooksDatabaseService extends Thread{
private Socket serviceSocket = null;
private String[] requestStr = new String[2]; //One slot for author's name and one for library's name.
private ResultSet outcome = null;
//JDBC connection
private String USERNAME = Credentials.USERNAME;
private String PASSWORD = Credentials.PASSWORD;
private String URL = Credentials.URL;
//Class constructor
public BooksDatabaseService(Socket aSocket){
serviceSocket = aSocket;
this.start();
}
//Retrieve the request from the socket
public String[] retrieveRequest()
{
StringBuilder sb = new StringBuilder();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(serviceSocket.getInputStream()));
int c = 0;
while (c != '#') {
c = in.read();
if (c == 0) {
System.out.println("reading null bytes");
System.exit(1);
}
sb.append((char) c);
}
}catch(IOException e){
System.out.println("Service thread " + this.getId() + ": " + e);
}
String inp = sb.toString();
this.requestStr = inp.substring(0, inp.length() - 1).split(";");
// returns [0]: author, [1]: city
return this.requestStr;
}
//Parse the request command and execute the query
public boolean attendRequest()
{
boolean flagRequestAttended = true;
this.outcome = null;
String sql = "select book.title, book.publisher, book.genre, book.rrp, count(*) as \"number_available\" from bookcopy join book on bookcopy.bookid = book.bookid where\n" +
"\tlibraryid = (select libraryid from \"library\" where city = ?) and\n" +
"\tbookcopy.bookid in (select bookid from book where authorid = (select authorid from author where familyname = ?))" +
// "\t and (onloan = false or onloan is null)\n" +
"group by book.title, book.publisher, book.genre, book.rrp;";
// city then author name
try {
//Connet to the database
Properties connectionProps = new Properties();
connectionProps.put("user", USERNAME);
connectionProps.put("password", PASSWORD);
Connection conn = DriverManager.getConnection(URL, connectionProps);
//Make the query
PreparedStatement q = conn.prepareStatement(sql);
q.setString(1, this.requestStr[1]); // city
q.setString(2, this.requestStr[0]); // author surname
//Process query
ResultSet res = q.executeQuery();
RowSetFactory aFactory = RowSetProvider.newFactory() ;
CachedRowSet crs = aFactory.createCachedRowSet();
crs.populate(res);
outcome = crs;
//Clean up
res.close();
q.close();
conn.close();
} catch (Exception e)
{ System.out.println(e); }
return flagRequestAttended;
}
//Wrap and return service outcome
public void returnServiceOutcome(){
try {
//Return outcome
ObjectOutputStream output = new ObjectOutputStream(serviceSocket.getOutputStream());
output.writeObject(outcome);
System.out.println("Service thread " + this.getId() + ": Service outcome returned; " + this.outcome);
//Terminating connection of the service socket
output.close();
serviceSocket.close();
}catch (IOException e){
System.out.println("Service thread " + this.getId() + ": " + e);
}
}
//The service thread run() method
public void run()
{
try {
System.out.println("\n============================================\n");
//Retrieve the service request from the socket
this.retrieveRequest();
System.out.println("Service thread " + this.getId() + ": Request retrieved: "
+ "author->" + this.requestStr[0] + "; library->" + this.requestStr[1]);
//Attend the request
boolean tmp = this.attendRequest();
//Send back the outcome of the request
if (!tmp)
System.out.println("Service thread " + this.getId() + ": Unable to provide service.");
this.returnServiceOutcome();
}catch (Exception e){
System.out.println("Service thread " + this.getId() + ": " + e);
}
//Terminate service thread (by exiting run() method)
System.out.println("Service thread " + this.getId() + ": Finished service.");
}
}