diff --git a/database.properties b/database.properties index e07b750..9067333 100644 --- a/database.properties +++ b/database.properties @@ -1,5 +1,5 @@ host=localhost port=5432 database=imdb -username= -password= +username=postgres +password=Test1234 diff --git a/src/main/kotlin/JDBCExerciseKotlinImplementation.kt b/src/main/kotlin/JDBCExerciseKotlinImplementation.kt index f3367fa..49368e4 100644 --- a/src/main/kotlin/JDBCExerciseKotlinImplementation.kt +++ b/src/main/kotlin/JDBCExerciseKotlinImplementation.kt @@ -4,15 +4,27 @@ import de.hpi.dbs1.JDBCExercise import de.hpi.dbs1.entities.Actor import de.hpi.dbs1.entities.Movie import java.sql.Connection +import java.sql.DriverManager +import java.sql.PreparedStatement +import java.sql.ResultSet +import java.sql.Statement +import java.util.Properties import java.util.logging.Logger -@ChosenImplementation(false) +@ChosenImplementation(true) class JDBCExerciseKotlinImplementation : JDBCExercise { val logger = Logger.getLogger(javaClass.simpleName) override fun createConnection(config: ConnectionConfig): Connection { - TODO("Not yet implemented") + val url = "jdbc:postgresql://${config.getHost()}:${config.getPort()}/${config.getDatabase()}" + val props: Properties = Properties().apply { + put("user", config.getUsername()) + put("password", config.getPassword()) + } + + val conn: Connection = DriverManager.getConnection(url, props) + return conn } override fun queryMovies( @@ -27,15 +39,92 @@ class JDBCExerciseKotlinImplementation : JDBCExercise { movies.add(myMovie) */ - TODO("Not yet implemented") + val st: PreparedStatement = connection.prepareStatement("SELECT * FROM tmovies WHERE \"primaryTitle\" LIKE ? ORDER BY \"primaryTitle\" ASC, \"startYear\" ASC;") + // NOTE: Why does Postgres count from 1?!!!! + st.setString(1, "%$keywords%") + val rs: ResultSet = st.executeQuery() + + while (rs.next()) { + val tconst = rs.getString("tconst") + val primaryTitle = rs.getString("primaryTitle") + val isAdult = rs.getBoolean("isAdult") + val startYear = rs.getInt("startYear") + val runtimeMinutes = rs.getInt("runtimeMinutes") + var genres = rs.getString("genres") + + // Remove prepending { and appending } from genres + if (genres.startsWith("{")) genres = genres.substring(1, genres.length - 1) + if (genres.endsWith("}")) genres = genres.substring(0, genres.length - 1) + + val movie = Movie( + tconst, primaryTitle, startYear, genres.split(",").toSet() + ) + + movies.add(movie) + } + + // Add actors to movies + for (movie in movies) { + val actorQuery = """ + SELECT nb.primaryname + FROM tprincipals tp + JOIN nbasics nb ON tp.nconst = nb.nconst + WHERE tp.tconst = ? + AND tp.category IN ('actor', 'actress') + ORDER BY nb.primaryname ASC; + """.trimIndent() + val actorSt: PreparedStatement = connection.prepareStatement(actorQuery) + actorSt.setString(1, movie.tConst) + val actorRs: ResultSet = actorSt.executeQuery() + while (actorRs.next()) { + movie.actorNames.add(actorRs.getString("primaryname")) + } + actorRs.close() + actorSt.close() + } + + rs.close() + st.close() + + return movies } - override fun queryActors( - connection: Connection, keywords: String - ): List { - logger.info(keywords) + override fun queryActors(connection: Connection, keywords: String): List { val actors = ArrayList() - TODO("Not yet implemented") + val actorQuery = """ + SELECT nconst, primaryname + FROM nbasics + WHERE primaryname ILIKE ? + AND nconst IN ( + SELECT nconst + FROM tprincipals + WHERE category IN ('actor', 'actress') + ) + ORDER BY ( + SELECT COUNT(*) + FROM tprincipals + WHERE tprincipals.nconst = nbasics.nconst + AND category IN ('actor', 'actress') + ) DESC, primaryname ASC + LIMIT 5; + """.trimIndent() + + val st = connection.prepareStatement(actorQuery) + st.setString(1, "%$keywords%") + val rs = st.executeQuery() + + while (rs.next()) { + val nconst = rs.getString("nconst") + val name = rs.getString("primaryname") + val actor = Actor(nconst, name) + + actors.add(actor) + } + + rs.close() + st.close() + + return actors } }