From c341b49d2e92115c46ba3d267139b560f0f6b124 Mon Sep 17 00:00:00 2001 From: hkarimx Date: Wed, 19 Nov 2025 20:23:37 +0100 Subject: [PATCH 1/3] Add Week1 DB exercises 3.1 and 3.2 --- Week1/assignment/exer1.js | 106 +++++++++++++++++++++++++++++++ Week1/assignment/exer2.js | 127 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 233 insertions(+) create mode 100644 Week1/assignment/exer1.js create mode 100644 Week1/assignment/exer2.js diff --git a/Week1/assignment/exer1.js b/Week1/assignment/exer1.js new file mode 100644 index 000000000..653a741c7 --- /dev/null +++ b/Week1/assignment/exer1.js @@ -0,0 +1,106 @@ +const { Client } = require("pg"); + +const DB_USER = "hyfuser"; +const DB_PASSWORD = "hyfpassword"; +const DB_HOST = "localhost"; +const DB_PORT = 5432; + +const baseConfig = { + host: DB_HOST, + port: DB_PORT, + user: DB_USER, + password: DB_PASSWORD, +}; + +async function withClient(database, handler) { + const client = new Client({ ...baseConfig, database }); + await client.connect(); + + try { + return await handler(client); + } finally { + await client.end(); + } +} + +async function setupMeetup() { + try { + // 1) Drop & recreate database meetup + await withClient("postgres", async (client) => { + console.log("Recreating database meetup..."); + + await client.query("DROP DATABASE IF EXISTS meetup;"); + await client.query("CREATE DATABASE meetup;"); + }); + + + await withClient("meetup", async (db) => { + console.log("Creating tables..."); + + await db.query(` + CREATE TABLE Invitee ( + invitee_no SERIAL PRIMARY KEY, + invitee_name VARCHAR(80) NOT NULL, + invited_by VARCHAR(80) NOT NULL + ); + `); + + await db.query(` + CREATE TABLE Room ( + room_no SERIAL PRIMARY KEY, + room_name VARCHAR(80) NOT NULL, + floor_number INTEGER NOT NULL + ); + `); + + await db.query(` + CREATE TABLE Meeting ( + meeting_no SERIAL PRIMARY KEY, + meeting_title VARCHAR(120) NOT NULL, + starting_time TIMESTAMP NOT NULL, + ending_time TIMESTAMP NOT NULL, + room_no INTEGER REFERENCES Room(room_no) + ); + `); + + console.log("Inserting sample data into Invitee..."); + await db.query(` + INSERT INTO Invitee (invitee_name, invited_by) VALUES + ('Karim', 'Majd'), + ('Rim', 'Karim'), + ('Alaa', 'Karim'), + ('Ivan', 'Majd'), + ('Dima', 'Ivan'); + `); + + console.log("Inserting sample data into Room..."); + await db.query(` + INSERT INTO Room (room_name, floor_number) VALUES + ('Alfa Room', 1), + ('Atlas Room', 1), + ('Nova Room', 2), + ('Fox Room', 2), + ('Sky Room', 3); + `); + + console.log("Inserting sample data into Meeting..."); + await db.query(` + INSERT INTO Meeting (meeting_title, starting_time, ending_time, room_no) VALUES + ('Intro to Databases', '2025-11-20 09:00', '2025-11-20 10:00', 1), + ('SQL Practice', '2025-11-20 10:30', '2025-11-20 11:30', 2), + ('Node & Postgres', '2025-11-21 09:00', '2025-11-21 10:30', 3), + ('Security Session', '2025-11-21 11:00', '2025-11-21 12:00', 4), + ('Retrospective Meetup', '2025-11-22 15:00', '2025-11-22 16:00', 5); + `); + }); + + console.log("Meetup database created and filled with data."); + } catch (err) { + console.error("Error while setting up meetup database:", err.message); + } +} + +setupMeetup().catch((err) => { + console.error("Unexpected error:", err); +}); + diff --git a/Week1/assignment/exer2.js b/Week1/assignment/exer2.js new file mode 100644 index 000000000..2f78aaab5 --- /dev/null +++ b/Week1/assignment/exer2.js @@ -0,0 +1,127 @@ +const { Client } = require("pg"); + +const DB_USER = "hyfuser"; +const DB_PASSWORD = "hyfpassword"; +const DB_HOST = "localhost"; +const DB_PORT = 5432; + +const client = new Client({ + user: DB_USER, + password: DB_PASSWORD, + host: DB_HOST, + port: DB_PORT, + database: "world", +}); + +async function runQuery(label, sql) { + console.log(`\n=== ${label} ===`); + + const result = await client.query(sql); + console.table(result.rows); +} + +async function runWorldQueries() { + + try { + + await client.connect(); + console.log("Connected to world database"); + + await runQuery("1) Countries with population greater than 8 million", + ` + SELECT name, population + FROM country + WHERE population > 8000000 + ORDER BY population DESC; + `); + + await runQuery('2) Countries that have "land" in their names', + ` + SELECT name + FROM country + WHERE name ILIKE '%land%' + ORDER BY name; + `); + + await runQuery("3) Cities with population between 500,000 and 1,000,000", + ` + SELECT name, population + FROM city + WHERE population BETWEEN 500000 AND 1000000 + ORDER BY population; + `); + + await runQuery("4) Countries on the continent 'Europe'", + ` + SELECT name + FROM country + WHERE continent = 'Europe' + ORDER BY name; + `); + + await runQuery("5) Countries ordered by surface area (descending)", + ` + SELECT name, surfacearea + FROM country + ORDER BY surfacearea DESC; + `); + + await runQuery("6) Cities in the Netherlands", + ` + SELECT c.name + FROM city AS c + JOIN country AS co ON c.countrycode = co.code + WHERE co.name = 'Netherlands' + ORDER BY c.name; + `); + + await runQuery("7) Population of Rotterdam", + ` + SELECT population + FROM city + WHERE name = 'Rotterdam'; + `); + + await runQuery("8) Top 10 countries by surface area", + ` + SELECT name, surfacearea + FROM country + ORDER BY surfacearea DESC + LIMIT 10; + `); + + await runQuery( + "9) Top 10 most populated cities", + ` + SELECT name, population + FROM city + ORDER BY population DESC + LIMIT 10; + `); + + await runQuery( + "10) Total world population", + ` + SELECT SUM(population) AS world_population + FROM country; + `); + + + console.log("\n All queries executed successfully."); + + } catch (err) { + + console.error("Error while running world queries:", err.message); + + } finally { + + await client.end(); + + console.log("Connection closed."); + } +} + + +runWorldQueries().catch((err) => { + console.error("Unexpected error:", err); +}); From b7764d1de1fc163eb806fd8053d88f1a05d12721 Mon Sep 17 00:00:00 2001 From: hkarimx Date: Wed, 26 Nov 2025 23:10:01 +0100 Subject: [PATCH 2/3] KARIM- W2 DB assignment added --- Week2/assignment/db.js | 13 +++++ Week2/assignment/ex1.js | 42 ++++++++++++++ Week2/assignment/ex2.js | 124 ++++++++++++++++++++++++++++++++++++++++ Week2/assignment/ex3.js | 48 ++++++++++++++++ Week2/assignment/ex4.js | 83 +++++++++++++++++++++++++++ 5 files changed, 310 insertions(+) create mode 100644 Week2/assignment/db.js create mode 100644 Week2/assignment/ex1.js create mode 100644 Week2/assignment/ex2.js create mode 100644 Week2/assignment/ex3.js create mode 100644 Week2/assignment/ex4.js diff --git a/Week2/assignment/db.js b/Week2/assignment/db.js new file mode 100644 index 000000000..5f1e96f0b --- /dev/null +++ b/Week2/assignment/db.js @@ -0,0 +1,13 @@ +import pg from "pg"; + +const { Pool } = pg; + +const pool = new Pool({ + host: process.env.DB_HOST ?? "localhost", + user: process.env.DB_USER ?? "hyfuser", + password: process.env.DB_PASSWORD ?? "hyfpassword", + database: process.env.DB_NAME ?? "research_w2", + port: Number(process.env.DB_PORT ?? 5432), +}); + +export default pool; diff --git a/Week2/assignment/ex1.js b/Week2/assignment/ex1.js new file mode 100644 index 000000000..0497d03f5 --- /dev/null +++ b/Week2/assignment/ex1.js @@ -0,0 +1,42 @@ +import pool from "./db.js"; + +async function run() { + try { + + await pool.query("DROP TABLE IF EXISTS authors CASCADE;"); + await pool.query(` + CREATE TABLE authors ( + author_id SERIAL PRIMARY KEY, + full_name VARCHAR(120) NOT NULL, + university VARCHAR(120), + date_of_birth DATE, + h_index INTEGER, + gender VARCHAR(10) + ); + `); + + + await pool.query(` + ALTER TABLE authors + ADD COLUMN mentor INTEGER; + `); + + + await pool.query(` + ALTER TABLE authors + ADD CONSTRAINT fk_authors_mentor + FOREIGN KEY (mentor) + REFERENCES authors (author_id) + ON DELETE SET NULL; + `); + + console.log("Exercise 1: authors table + mentor FK created"); + } catch (err) { + console.error("Error in ex1-keys:", err.message); + } finally { + await pool.end(); + console.log("Connection closed"); + } +} + +run(); diff --git a/Week2/assignment/ex2.js b/Week2/assignment/ex2.js new file mode 100644 index 000000000..a54890e5e --- /dev/null +++ b/Week2/assignment/ex2.js @@ -0,0 +1,124 @@ +import pool from "./db.js"; + +const authorRows = [ + ["Noah Clarke", "TU Eindhoven", "1981-04-11", 14, "M"], + ["Mila Verhoef", "Utrecht University", "1986-09-02", 18, "F"], + ["Jonas Peters", "TU Delft", "1979-12-23", 22, "M"], + ["Sara Koster", "University of Twente", "1990-03-19", 11, "F"], + ["Liam de Bruin", "VU Amsterdam", "1984-07-08", 16, "M"], + ["Nadia Rossi", "Leiden University", "1988-01-28", 19, "F"], + ["Omar Haddad", "University of Amsterdam", "1977-10-04", 24, "M"], + ["Elif Kaya", "Radboud University", "1989-06-15", 13, "F"], + ["Lucas Stein", "Ruhr University Bochum", "1982-11-30", 20, "M"], + ["Yara Hussain", "Ghent University", "1991-02-05", 9, "F"], + ["Tobias Meier", "ETH Zürich", "1980-08-12", 26, "M"], + ["Rosa Almeida", "University of Porto", "1987-05-27", 17, "F"], + ["Imran Malik", "KU Leuven", "1992-01-09", 7, "M"], + ["Emma Jansen", "Hanze University", "1993-09-14", 5, "F"], + ["Felix Novak", "Charles University", "1985-12-03", 12, "M"], +]; + +async function seedAuthors() { + + await pool.query("TRUNCATE TABLE authors RESTART IDENTITY CASCADE;"); + + const insertSql = ` + INSERT INTO authors (full_name, university, date_of_birth, h_index, gender) + VALUES ($1, $2, $3, $4, $5); + `; + + for (const row of authorRows) { + await pool.query(insertSql, row); + } + + await pool.query("UPDATE authors SET mentor = 3 WHERE author_id = 1;"); + await pool.query("UPDATE authors SET mentor = 3 WHERE author_id = 2;"); + await pool.query("UPDATE authors SET mentor = 5 WHERE author_id = 4;"); + await pool.query("UPDATE authors SET mentor = 2 WHERE author_id = 5;"); + await pool.query("UPDATE authors SET mentor = 7 WHERE author_id = 6;"); + await pool.query("UPDATE authors SET mentor = 1 WHERE author_id = 8;"); + await pool.query("UPDATE authors SET mentor = 10 WHERE author_id = 9;"); + await pool.query("UPDATE authors SET mentor = 11 WHERE author_id = 10;"); + await pool.query("UPDATE authors SET mentor = 4 WHERE author_id = 11;"); + await pool.query("UPDATE authors SET mentor = 6 WHERE author_id = 12;"); + +} + +async function createPaperTables() { + await pool.query("DROP TABLE IF EXISTS authors_papers;"); + await pool.query("DROP TABLE IF EXISTS research_papers;"); + + await pool.query(` + CREATE TABLE research_papers ( + paper_id SERIAL PRIMARY KEY, + paper_title VARCHAR(200) NOT NULL, + conference VARCHAR(100), + publish_date DATE + ); + `); + + await pool.query(` + CREATE TABLE authors_papers ( + author_id INTEGER REFERENCES authors(author_id) ON DELETE CASCADE, + paper_id INTEGER REFERENCES research_papers(paper_id) ON DELETE CASCADE, + PRIMARY KEY (author_id, paper_id) + ); + `); +} + +async function seedPapersAndLinks() { + + for (let i = 1; i <= 30; i += 1) { + await pool.query( + ` + INSERT INTO research_papers (paper_title, conference, publish_date) + VALUES ($1, $2, $3); + `, + [`Study on Databases ${i}`, `DataConf ${((i - 1) % 5) + 1}`, `202${i % 4}-0${((i - 1) % 9) + 1}-15`] + ); + } + + + const links = [ + [1, 1], [1, 2], [2, 3], + [3, 4], [3, 5], + [4, 6], + [5, 7], [5, 8], [5, 9], + [6, 10], + [7, 11], [7, 12], + [8, 13], + [9, 14], [9, 15], + [10, 16], [10, 17], + [11, 18], [11, 19], [11, 20], + [12, 21], + [13, 22], + [14, 23], [14, 24], + [1, 25], [2, 26], [3, 27], [4, 28], [6, 29], [7, 30], + ]; + + for (const [authorId, paperId] of links) { + await pool.query( + ` + INSERT INTO authors_papers (author_id, paper_id) + VALUES ($1, $2); + `, + [authorId, paperId] + ); + } +} + +async function run() { + try { + await createPaperTables(); + await seedAuthors(); + await seedPapersAndLinks(); + console.log("Exercise 2: tables created and data inserted"); + } catch (err) { + console.error("Error in ex2-relationships:", err.message); + } finally { + await pool.end(); + console.log("Connection closed"); + } +} + +run(); diff --git a/Week2/assignment/ex3.js b/Week2/assignment/ex3.js new file mode 100644 index 000000000..6357e4e3f --- /dev/null +++ b/Week2/assignment/ex3.js @@ -0,0 +1,48 @@ +import pool from "./db.js"; + +async function run() { + try { + + const q1 = ` + SELECT + a.author_id, + a.full_name AS author_name, + m.full_name AS mentor_name + FROM authors a + LEFT JOIN authors m + ON a.mentor = m.author_id + ORDER BY a.author_id; + `; + const res1 = await pool.query(q1); + console.log("\nAuthors with their mentors"); + console.table(res1.rows); + + + const q2 = ` + SELECT + a.author_id, + a.full_name, + a.university, + a.date_of_birth, + a.h_index, + a.gender, + rp.paper_title + FROM authors a + LEFT JOIN authors_papers ap + ON a.author_id = ap.author_id + LEFT JOIN research_papers rp + ON ap.paper_id = rp.paper_id + ORDER BY a.author_id, rp.paper_title; + `; + const res2 = await pool.query(q2); + console.log("\nAuthors with their paper titles (if any)"); + console.table(res2.rows); + } catch (err) { + console.error("Error in ex3-joins:", err.message); + } finally { + await pool.end(); + console.log("Connection closed"); + } +} + +run(); diff --git a/Week2/assignment/ex4.js b/Week2/assignment/ex4.js new file mode 100644 index 000000000..a44c25e3b --- /dev/null +++ b/Week2/assignment/ex4.js @@ -0,0 +1,83 @@ +import pool from "./db.js"; + +async function run() { + try { + + const q1 = ` + SELECT + rp.paper_id, + rp.paper_title, + COUNT(ap.author_id) AS author_count + FROM research_papers rp + LEFT JOIN authors_papers ap + ON rp.paper_id = ap.paper_id + GROUP BY rp.paper_id, rp.paper_title + ORDER BY rp.paper_id; + `; + const res1 = await pool.query(q1); + console.log("\n1) Papers and number of authors"); + console.table(res1.rows); + + const q2 = ` + SELECT + COUNT(DISTINCT ap.paper_id) AS total_papers_by_female_authors + FROM authors a + JOIN authors_papers ap + ON a.author_id = ap.author_id + WHERE a.gender = 'F'; + `; + + const res2 = await pool.query(q2); + console.log("\n2) Total papers by female authors"); + console.table(res2.rows); + + const q3 = ` + SELECT + university, + AVG(h_index) AS average_h_index + FROM authors + GROUP BY university + ORDER BY university; + `; + + const res3 = await pool.query(q3); + console.log("\n3) Average h-index per university"); + console.table(res3.rows); + + + const q4 = ` + SELECT + a.university, + COUNT(DISTINCT ap.paper_id) AS total_papers + FROM authors a + LEFT JOIN authors_papers ap + ON a.author_id = ap.author_id + GROUP BY a.university + ORDER BY a.university; + `; + const res4 = await pool.query(q4); + console.log("\n4) Total papers per university"); + console.table(res4.rows); + + const q5 = ` + SELECT + university, + MIN(h_index) AS min_h_index, + MAX(h_index) AS max_h_index + FROM authors + GROUP BY university + ORDER BY university; + `; + + const res5 = await pool.query(q5); + console.log("\n5) Min/Max h-index per university"); + console.table(res5.rows); + } catch (err) { + console.error("Error in ex4-aggregate-functions:", err.message); + } finally { + await pool.end(); + console.log("Connection closed"); + } +} + +run(); From 9b6bf372bb54722f77fe936a4f63366c4d2bb006 Mon Sep 17 00:00:00 2001 From: hkarimx Date: Sun, 21 Dec 2025 15:05:41 +0100 Subject: [PATCH 3/3] Week2 fixed --- Week2/assignment/db.js | 20 +++--- Week2/assignment/ex1.js | 47 +++++++------- Week2/assignment/ex2.js | 135 +++++++++++++++++++++++----------------- Week2/assignment/ex3.js | 53 ++++++++-------- 4 files changed, 136 insertions(+), 119 deletions(-) diff --git a/Week2/assignment/db.js b/Week2/assignment/db.js index 5f1e96f0b..8c881fc51 100644 --- a/Week2/assignment/db.js +++ b/Week2/assignment/db.js @@ -1,13 +1,13 @@ import pg from "pg"; -const { Pool } = pg; +const { Client } = pg; -const pool = new Pool({ - host: process.env.DB_HOST ?? "localhost", - user: process.env.DB_USER ?? "hyfuser", - password: process.env.DB_PASSWORD ?? "hyfpassword", - database: process.env.DB_NAME ?? "research_w2", - port: Number(process.env.DB_PORT ?? 5432), -}); - -export default pool; +export function createClient() { + return new Client({ + host: process.env.DB_HOST ?? "localhost", + user: process.env.DB_USER ?? "hyfuser", + password: process.env.DB_PASSWORD ?? "hyfpassword", + database: process.env.DB_NAME ?? "research_w2", + port: Number(process.env.DB_PORT ?? 5432), + }); +} diff --git a/Week2/assignment/ex1.js b/Week2/assignment/ex1.js index 0497d03f5..8efb6367a 100644 --- a/Week2/assignment/ex1.js +++ b/Week2/assignment/ex1.js @@ -1,28 +1,29 @@ -import pool from "./db.js"; +import { createClient } from "./db.js"; async function run() { - try { - - await pool.query("DROP TABLE IF EXISTS authors CASCADE;"); - await pool.query(` - CREATE TABLE authors ( - author_id SERIAL PRIMARY KEY, - full_name VARCHAR(120) NOT NULL, - university VARCHAR(120), - date_of_birth DATE, - h_index INTEGER, - gender VARCHAR(10) - ); - `); + const client = createClient(); - - await pool.query(` - ALTER TABLE authors - ADD COLUMN mentor INTEGER; - `); - - - await pool.query(` + try { + await client.connect(); + + await client.query("DROP TABLE IF EXISTS authors CASCADE;"); + await client.query(` + CREATE TABLE authors ( + author_id SERIAL PRIMARY KEY, + full_name VARCHAR(120) NOT NULL, + university VARCHAR(120), + date_of_birth DATE NOT NULL, + h_index INTEGER, + gender CHAR(1) NOT NULL CHECK (gender IN ('M', 'F')) + ); + `); + + await client.query(` + ALTER TABLE authors + ADD COLUMN mentor INTEGER; + `); + + await client.query(` ALTER TABLE authors ADD CONSTRAINT fk_authors_mentor FOREIGN KEY (mentor) @@ -34,7 +35,7 @@ async function run() { } catch (err) { console.error("Error in ex1-keys:", err.message); } finally { - await pool.end(); + await client.end(); console.log("Connection closed"); } } diff --git a/Week2/assignment/ex2.js b/Week2/assignment/ex2.js index a54890e5e..97d53d31f 100644 --- a/Week2/assignment/ex2.js +++ b/Week2/assignment/ex2.js @@ -1,26 +1,29 @@ -import pool from "./db.js"; +import { createClient } from "./db.js"; const authorRows = [ - ["Noah Clarke", "TU Eindhoven", "1981-04-11", 14, "M"], - ["Mila Verhoef", "Utrecht University", "1986-09-02", 18, "F"], - ["Jonas Peters", "TU Delft", "1979-12-23", 22, "M"], - ["Sara Koster", "University of Twente", "1990-03-19", 11, "F"], + ["Noah Clarke", "TU Delft", "1981-04-11", 14, "M"], + ["Mila Verhoef", "TU Delft", "1986-09-02", 18, "F"], + ["Jonas Peters", "TU Eindhoven", "1979-12-23", 22, "M"], + ["Sara Koster", "TU Eindhoven", "1990-03-19", 11, "F"], ["Liam de Bruin", "VU Amsterdam", "1984-07-08", 16, "M"], - ["Nadia Rossi", "Leiden University", "1988-01-28", 19, "F"], - ["Omar Haddad", "University of Amsterdam", "1977-10-04", 24, "M"], - ["Elif Kaya", "Radboud University", "1989-06-15", 13, "F"], - ["Lucas Stein", "Ruhr University Bochum", "1982-11-30", 20, "M"], - ["Yara Hussain", "Ghent University", "1991-02-05", 9, "F"], + ["Nadia Rossi", "VU Amsterdam", "1988-01-28", 19, "F"], + ["Elif Kaya", "University of Amsterdam", "1989-06-15", 13, "F"], + ["Lucas Stein", "Radboud University", "1982-11-30", 20, "M"], + ["Yara Hussain", "Radboud University", "1991-02-05", 9, "F"], ["Tobias Meier", "ETH Zürich", "1980-08-12", 26, "M"], - ["Rosa Almeida", "University of Porto", "1987-05-27", 17, "F"], + ["Rosa Almeida", "ETH Zürich", "1987-05-27", 17, "F"], ["Imran Malik", "KU Leuven", "1992-01-09", 7, "M"], - ["Emma Jansen", "Hanze University", "1993-09-14", 5, "F"], + ["Emma Jansen", "KU Leuven", "1993-09-14", 5, "F"], ["Felix Novak", "Charles University", "1985-12-03", 12, "M"], + ["Omar Haddad", "University of Amsterdam", "1977-10-04", 24, "M"], ]; -async function seedAuthors() { +function pad2(n) { + return String(n).padStart(2, "0"); +} - await pool.query("TRUNCATE TABLE authors RESTART IDENTITY CASCADE;"); +async function seedAuthors(client) { + await client.query("TRUNCATE TABLE authors RESTART IDENTITY CASCADE;"); const insertSql = ` INSERT INTO authors (full_name, university, date_of_birth, h_index, gender) @@ -28,27 +31,35 @@ async function seedAuthors() { `; for (const row of authorRows) { - await pool.query(insertSql, row); + await client.query(insertSql, row); } - await pool.query("UPDATE authors SET mentor = 3 WHERE author_id = 1;"); - await pool.query("UPDATE authors SET mentor = 3 WHERE author_id = 2;"); - await pool.query("UPDATE authors SET mentor = 5 WHERE author_id = 4;"); - await pool.query("UPDATE authors SET mentor = 2 WHERE author_id = 5;"); - await pool.query("UPDATE authors SET mentor = 7 WHERE author_id = 6;"); - await pool.query("UPDATE authors SET mentor = 1 WHERE author_id = 8;"); - await pool.query("UPDATE authors SET mentor = 10 WHERE author_id = 9;"); - await pool.query("UPDATE authors SET mentor = 11 WHERE author_id = 10;"); - await pool.query("UPDATE authors SET mentor = 4 WHERE author_id = 11;"); - await pool.query("UPDATE authors SET mentor = 6 WHERE author_id = 12;"); + const mentorPairs = [ + [1, 3], + [2, 3], + [4, 5], + [5, 2], + [6, 7], + [8, 1], + [9, 10], + [10, 11], + [11, 4], + [12, 6], + ]; + for (const [authorId, mentorId] of mentorPairs) { + await client.query("UPDATE authors SET mentor = $1 WHERE author_id = $2;", [ + mentorId, + authorId, + ]); + } } -async function createPaperTables() { - await pool.query("DROP TABLE IF EXISTS authors_papers;"); - await pool.query("DROP TABLE IF EXISTS research_papers;"); +async function createPaperTables(client) { + await client.query("DROP TABLE IF EXISTS authors_papers;"); + await client.query("DROP TABLE IF EXISTS research_papers;"); - await pool.query(` + await client.query(` CREATE TABLE research_papers ( paper_id SERIAL PRIMARY KEY, paper_title VARCHAR(200) NOT NULL, @@ -57,66 +68,74 @@ async function createPaperTables() { ); `); - await pool.query(` + await client.query(` CREATE TABLE authors_papers ( - author_id INTEGER REFERENCES authors(author_id) ON DELETE CASCADE, - paper_id INTEGER REFERENCES research_papers(paper_id) ON DELETE CASCADE, + author_id INTEGER NOT NULL REFERENCES authors(author_id) ON DELETE CASCADE, + paper_id INTEGER NOT NULL REFERENCES research_papers(paper_id) ON DELETE CASCADE, PRIMARY KEY (author_id, paper_id) ); `); } -async function seedPapersAndLinks() { +async function seedPapersAndLinks(client) { for (let i = 1; i <= 30; i += 1) { - await pool.query( + const month = pad2(((i - 1) % 9) + 1); + const year = 2020 + (i % 4); + const date = `${year}-${month}-15`; + + await client.query( ` INSERT INTO research_papers (paper_title, conference, publish_date) VALUES ($1, $2, $3); - `, - [`Study on Databases ${i}`, `DataConf ${((i - 1) % 5) + 1}`, `202${i % 4}-0${((i - 1) % 9) + 1}-15`] + `, + [`Study on Databases ${i}`, `DataConf ${((i - 1) % 5) + 1}`, date] ); } const links = [ - [1, 1], [1, 2], [2, 3], - [3, 4], [3, 5], - [4, 6], - [5, 7], [5, 8], [5, 9], - [6, 10], - [7, 11], [7, 12], - [8, 13], - [9, 14], [9, 15], - [10, 16], [10, 17], - [11, 18], [11, 19], [11, 20], - [12, 21], - [13, 22], - [14, 23], [14, 24], - [1, 25], [2, 26], [3, 27], [4, 28], [6, 29], [7, 30], + [1, 1], [2, 1], [3, 1], + [4, 2], [5, 2], + [6, 3], [7, 3], + [8, 4], [9, 4], [10, 4], + [11, 5], + [12, 6], + [13, 7], + [14, 8], + [15, 9], + [1, 10], [5, 10], + [2, 11], [6, 11], [9, 11], + [3, 12], [4, 13], [7, 14], [8, 15], [10, 16], + [11, 17], [12, 18], [13, 19], [14, 20], [15, 21], ]; for (const [authorId, paperId] of links) { - await pool.query( + await client.query( ` INSERT INTO authors_papers (author_id, paper_id) VALUES ($1, $2); - `, + `, [authorId, paperId] ); } } async function run() { + const client = createClient(); + try { - await createPaperTables(); - await seedAuthors(); - await seedPapersAndLinks(); - console.log("Exercise 2: tables created and data inserted"); + await client.connect(); + + await createPaperTables(client); + await seedAuthors(client); + await seedPapersAndLinks(client); + + console.log("Exercise 2: papers + links seeded (includes multi-author papers)"); } catch (err) { - console.error("Error in ex2-relationships:", err.message); + console.error("Error in ex2:", err.message); } finally { - await pool.end(); + await client.end(); console.log("Connection closed"); } } diff --git a/Week2/assignment/ex3.js b/Week2/assignment/ex3.js index 6357e4e3f..e68889d29 100644 --- a/Week2/assignment/ex3.js +++ b/Week2/assignment/ex3.js @@ -1,46 +1,43 @@ -import pool from "./db.js"; +import { createClient } from "./db.js"; async function run() { + const client = createClient(); + try { + await client.connect(); const q1 = ` - SELECT - a.author_id, - a.full_name AS author_name, - m.full_name AS mentor_name - FROM authors a - LEFT JOIN authors m - ON a.mentor = m.author_id - ORDER BY a.author_id; - `; - const res1 = await pool.query(q1); + SELECT + a.author_id, + a.full_name AS author_name, + m.full_name AS mentor_name + FROM authors a + LEFT JOIN authors m + ON a.mentor = m.author_id + ORDER BY a.author_id; + `; + const res1 = await client.query(q1); console.log("\nAuthors with their mentors"); console.table(res1.rows); const q2 = ` - SELECT - a.author_id, - a.full_name, - a.university, - a.date_of_birth, - a.h_index, - a.gender, - rp.paper_title - FROM authors a - LEFT JOIN authors_papers ap - ON a.author_id = ap.author_id - LEFT JOIN research_papers rp - ON ap.paper_id = rp.paper_id - ORDER BY a.author_id, rp.paper_title; - `; - const res2 = await pool.query(q2); + SELECT a.*, rp.paper_title + FROM authors a + LEFT JOIN authors_papers ap + ON a.author_id = ap.author_id + LEFT JOIN research_papers rp + ON ap.paper_id = rp.paper_id + ORDER BY a.author_id, rp.paper_title; + `; + + const res2 = await client.query(q2); console.log("\nAuthors with their paper titles (if any)"); console.table(res2.rows); } catch (err) { console.error("Error in ex3-joins:", err.message); } finally { - await pool.end(); + await client.end(); console.log("Connection closed"); } }